ASCII 문자 혼란


24

인쇄 가능한 문자 (ASCII 20-7E)와 n[2,16] 의 정수로 구성된 문자열을 입력으로 사용하고 문자열에 대해 다음 수정을 수행하는 프로그램을 작성하십시오.

  • 문자열의 각 문자는 ASCII 코드로 변환됩니다 (주어진 예제는 16 진수이지만 10 진수도 허용됩니다).
  • ASCII 코드는 기본으로 변환되어 n서로 연결됩니다.
  • 새 문자열은 다른 모든 문자로 분할됩니다. 홀수 개의 문자가 있으면 마지막 문자가 완전히 제거됩니다.
  • 인쇄 ASCII 코드 (16 진수)는 문자로 다시 변환되고 인쇄되지 않는 ASCII 코드는 제거됩니다.
  • 결과 문자열이 인쇄됩니다.

테스트 사례

입력

Hello, World!
6

단계

Hello, World!
48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21
2002453003003031125222330331030024453
20 02 45 30 03 00 30 31 12 52 22 33 03 31 03 00 24 45

이 프로그램의 출력은입니다 E001R"31$E.


이것은 코드 골프이므로 표준 규칙이 적용됩니다. 바이트 단위의 최단 코드가 이깁니다.


이 인코딩 알고리즘은 비밀 메시지를 보내는 데 유용 할 수 있습니다!
Kritixi Lithos

언젠가이 일을해야 해요!
anOKsquirrel

@ ΚριτικσιΛίθος 프로그램이 가능한 모든 입력 문자열에 대해 작동하는 동안 모든 출력 문자열이 고유하지는 않습니다. 예를 들어, base 7에서 문자열 J은 또는 - 처럼 J-> 50-> 101-> 10-> 단계를 거칩니다 . (no output)KL
Arcturus

@Eridan이 말했듯이 홀수 시퀀스가 ​​마지막 문자를 제거하기 때문에 이것은 손실되는 암호화입니다. 나는 무지한 관찰자에게 확신하지만 그것은 : 통신의 snarky의 방법이 될 수있다
DoctorHeckle

1
1 단계는 혼란 스럽습니다-문자를 16 진수로 변환 할 필요가 없습니다-예 : HASCII 72 (십진수) 또는 48 (16 진수)이지만 필요한 것은 200 (기본 6)입니다. 예제의 모든 행 2는 쓸모없고 내 의견으로는 혼란 스럽습니다
edc65

답변:




3

배쉬 + 일반적인 리눅스 유틸리티, 118

printf %s "$1"|xxd -p|sed -r "s/../\U& /g;y/ /n/;s/^/dc -e$2o16i/e;s/../& /g;s/ .$//;"|xxd -rp|sed 's/[^[:print:]]//g'

난 당신이 단축 수 있다고 생각 printf %s "$1"echo -n "$1"2 바이트 저장
아론

@Aaron 입력 문자열이 -e입니다. 시도echo -n "-e"
Digital Trauma

젠장, 멋지게 발견되었습니다!
Aaron

2

CJam, 24 바이트

l:irifbe_2/{Gbc',32>&}/

'와 사이에 DEL 문자 (0x7F)가 ,있습니다. CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

l:i                     Read a line from STDIN and cast each char to integer. 
   ri                   Read another integer (base) from STDIN.
     fb                 Convert each integer from line 1 to that base.
       e_2/             Flatten and split into chunks of length 2.
                        If the last chunk has only one element, it will get
                        converted into a control character, which will be
                        removed later.
          {         }/  For each digit pair:
           Gb             Convert the pair from base 16 to integer.
             c            Cast to character.
              ',          Push the string of ASCII characters up to '~'.
                32>       Remove the first 32 (control characters).
                   &      Intersect.

DEL 캐릭터는 어떻습니까? 당신이 그 문제를 해결 한 것처럼 보이지만 설명에서는 볼 수 없습니다!
wizzwizz4

StackExchange는 인쇄 할 수없는 문자를 필터링합니다. DEL 캐릭터는 오직 퍼머 링크에만 존재하며 거기에서도 보이지 않습니다.
Dennis

내 말은 ... 삭제는 제어 문자이지만 처음 32 자 중 하나가 아닙니다. ASCII에 익숙하지 않은 사람들에게는 문자 번호 127, 0x7F입니다.
wizzwizz4

귀하의 질문을 이해하지 못했습니다. 출력에서 어떻게 필터링하는지 궁금하십니까?
Dennis

예. 코드 설명이 DEL출력 에서 문자 를 필터링하는 방법을 말하지 않는 것 같습니다 .
wizzwizz4

2

자바 스크립트 (ES6), 137 147

JavaScript에서 사용 가능한 가장 자세한 기능 사용

f=(s,b)=>alert(s.replace(/./g,x=>x.charCodeAt().toString(b)).match(/../g).map(x=>(x=String.fromCharCode('0x'+x))<='~'&x>' '?x:'').join``)

// Just for test purpose, redefine alert()
alert=x=>document.write('<pre>'+x+'</pre>')

f('Hello, World!',6)
f('PORK',3)



[for(z of ...)if(...)...]대신에 바이트를 사용하여 바이트를 절약 할 수 있다고 생각합니다.map(...).filter(...)
Ypnypn

@ Ypnypn 나는 힌트를 사용하는 방법을 찾지 못했지만 (ES7 인 배열 이해를 제외하고) 모든 것을 다시 생각해야했습니다. 고마워. 난 당신이 한 경우에도 계속 바랍니다 x=>x>=
edc65

1
ES7 사용에 어떤 문제가 있습니까?
Ypnypn

1
@Ypnypn 나는 <
parroll

1

줄리아, 118 바이트

f(s,n)=join(map(i->(c=string(Char(parse(Int,i,16))))^isprint(c),matchall(r"..",join(map(i->base(n,Int(i)),[s...])))))

언 골프 드 :

function f(s::AbstractString, n::Integer)
    # Construct an array of ASCII codes in base n
    v = map(i -> base(n, Int(i)), [s...])

    # Join into a string and get all pairs, truncating
    # to an even length
    m = matchall(r"..", join(v))

    # Parse each pair as an integer in base 16, get the
    # character associated with that code point, convert
    # to a string, and include if it's printable
    x = map(i -> (c = string(Char(parse(Int, i, 16)))^isprint(c), m)

    # Join as a string and return
    return join(x)
end

1

수학, 134 바이트

Print@FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@InputString[]~IntegerString~Input[],2],31<#<127&]

기능이 허용되는 경우 :

수학, 112 바이트

FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@#~IntegerString~#2,2],31<#<127&]&

1

티 스크립트, 23 바이트

TeaScript는 골프를위한 JavaScript입니다

£lc¡T(y©K(2)ßC(P(l,16±µ

비교적 간단하지만 유쾌하게 짧습니다. 더 많은 연산자를 사용하여 캐릭터를 몇 개 더 내릴 수 있습니다. 다른 몇 가지 새로운 기능을 사용하여 일부 바이트를 줄일 수도 있습니다.

Ungolfed && 설명

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``

1
나는 이것이 23 (29 바이트 ) 길이 라고 생각합니다 .
크리스티안 루 파스

w0lf @ 즉 UTF-8 인코딩 할 것이지만, 모든 문자 미만 256이기 때문에 우리는 안전하게 한 바이트로 셀 수
Downgoat


1

파이썬 2, 174 바이트

def J(a,b,i=0):
 h=r=''
 B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
 for c in a:h+=B(ord(c),b)
 while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
 print r

여기 사용해보십시오

실제로 작업에 가장 적합한 도구는 아닙니다. 파이썬에는 임의의 기본 변환 기능이 없으므로 직접 구현해야했습니다. 적어도 재미있었습니다. 특히 숫자보다 [마지막으로] 짧은 표현을 찾는 것보다 "0123456789ABCDEF"[n%b]. 한 번에 두 문자 이상을 반복하기 위해while 루프가 기능적 접근 방식보다 약간 짧았습니다.

전체 프로그램으로 181 바이트 :

B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
a=raw_input()
b=input()
h=r=''
for c in a:h+=B(ord(c),b)
i=0
while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
print r

0

MATLAB, 103 바이트

function k(s,n),b=dec2base(s,n)';b(~cumsum(b-'0',1))='';c=base2dec(textscan(b,'%2c'),16)';char(c(c>31))

문자열 s 와 정수 n 을 입력으로 사용 하는 함수 k 를 작성했습니다 . 예 :

k('Hello, World!',6)

준다

 E001R"31$E

내가 해결해야 할 가장 성가신 일은 base n으로 변환 할 때 0이 나타나는 것 입니다. 두 번째 문자마다 분할 될 배열에서 이것을 제거하는 데는 많은 바이트가 필요했습니다. 이 방법을 사용하여 더 이상 바이트를 저장할 수 있는지 확실하지 않습니다.


0

PHP-286 바이트

문자열을 입력 $s하고 정수를 입력하십시오 $b.

<?php $s=$_GET["s"];$b;$m="array_map";echo implode($m(function($v){return ctype_print($v)?$v:"";},$m("chr",$m("hexdec",str_split(strlen(implode($a=$m(function($v){global$b;return base_convert($v,16,$b);},$m("dechex",$m("ord",str_split($s))))))%2==1?substr(implode($a),0,-1):$a,2)))));?>

에 값을 전달하십시오 GET["s"].

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.