다음 사양에 따라 데이터를 암호화 및 해독 할 프로그램 또는 기능 (또는 프로그램 / 기능 세트)을 작성하십시오.
암호화
-
모든 바이트를 서로 XOR하여 XOR 해시를 계산합니다.
-
이 해시에 의해 입력의 모든 바이트를 XOR합니다.
-
결과를 4 비트 왼쪽으로 이동합니다.
-
XOR 해시의 처음 4 비트로 왼쪽을 채 웁니다.
-
XOR 해시의 마지막 4 비트로 오른쪽을 채 웁니다.
예
-
주어진 입력 :
"G0lf"
(0x47306C66
) -
XOR 해시를 계산하십시오.
0x47 ^ 0x30 ^ 0x6C ^ 0x66 = 0x7D
-
해시별로 모든 바이트 XOR :
0x3A4D111B
-
예상 결과 (shift 및 pad 후) :
"s¤Ñ\x11½"
(0x73A4D111BD
)
규칙
-
프로그램 / 기능은 입력 / 출력 이 실제 바이트 인 경우 골프 언어 선택 (문자열, 바이트 배열 등) 에서 의미가있는 모든 유형의 입력 / 출력을 수행 할 수 있습니다 . 예를 들어 16 진 문자열을 출력 할 수 없습니다.
-
암호화와 암호 해독은 별도의 프로그램 (점수는 결합 된 크기 임) 또는 단일 프로그램으로 분리 될 수 있습니다. 단일 메소드는 암호화 또는 복호화 여부에 대한 인수를 취할 수 있습니다.
-
암호화 입력의 크기는 1 바이트 이상이어야합니다.
-
암호 해독을위한 입력은 2 바이트 이상일 것으로 예상 할 수 있습니다.
-
인쇄 할 수없는 바이트는 출력에서 이스케이프 할 필요가 없습니다.
답변
CJam, 28 + 27 = 55 바이트
각 부분에 대해 입력 / 출력이 정수 배열의 형태가 될 것으로 기대하는 하나의 프로그램과 문자열을 사용하는 하나의 프로그램을 제시합니다. 위의 바이트 수는 정수 배열 버전에 대한 것이지만 연결된 스크립트와 설명은 문자열 기반 버전에 대한 것입니다 (질문에 주어진 예제를 테스트하는 데 사용할 수 있음).
암호화
q~_:^_GbYUe[\@f^Gfbe_*2/Gfbp
q:i_:^_GbYUe[\@f^Gfbe_*2/Gfb:c
복호화
q~{_G/\G%}%)\(G*@+\2/Gfbf^p
q:i{_G/\G%}%)\(G*@+\2/Gfbf^:c
다음은 전체 왕복을 수행하고 암호 해독을 다시 수행하기 전에 암호화 된 코드를 인쇄 하는 테스트 스크립트 입니다.
설명
q:i_:^_GbYUe[\@f^Gfbe_*2/Gfb:c
q:i e# Read the input and convert characters to byte values.
_:^ e# Duplicate and fold XOR onto the characters to get
e# the hash.
_Gb e# Duplicate and convert to base 16 to get nibbles.
YUe[ e# Pad to width 2 with zeroes.
\@ e# Pull up other copy and integer array.
f^ e# XOR each integer with the hash.
Gfbe_ e# Convert each result to base 16 and flatten that.
* e# Join the hash nibbles with this array.
2/ e# Split into pairs.
Gfb e# Interpret each pair as base 16.
:c e# Convert each integer to a character.
q:i{_G/\G%}%)\(G*@+\2/Gfbf^:c
q:i e# Read the input and convert characters to byte values.
{ }% e# Map this block onto each byte.
_G/\G% e# Get the two base 16 digits individually.
)\( e# Slice off the last and first nibble.
G*@+\ e# Combine into byte (the hash) and swap with array.
2/Gfb e# Split array into pairs and interpret each as base 16.
f^ e# XOR each with the hash.
:c e# Convert each integer to a character.
답변
CJam, 36 + 34 = 70 바이트
이진 형식을 사용하는 조금 다른 접근 방식
암호화 기 :
q_:^:Hf^H+{i2b8Ue[}%)4/~@\]e_8/2fb:c
작동 방식 :
q_:^ e# Read input as string, copy and XOR all the chars
:Hf^ e# Store the XOR in H and XOR each char with H
H+ e# Append H to the char array
{ }% e# On each of the elements in the array
i2b e# Convert the ASCII value to binary
8Ue[ e# Pad with 0 so that the length is 8
) e# Pop out the last array element, which is H
4/~@\ e# Put first 4 bits of H before the input array
e# And rest 4 after it
]e_8/ e# Flatten everything into a single array and group
e# into pieces of 8 bits
2fb:c e# Convert each 8 bit part to integer and then to
e# its character form
암호 해독기 :
q{i2b8Ue[4/~}%)\(@+2b\:+8/2fb\f^:c
작동 방식 :
q{ }% e# For each character of the input string
i2b e# Convert to ASCII code and then to its binary form
8Ue[ e# Pad with enough 0 so that length is 8 bit
4/~ e# Split into parts of 4 and unwrap
)\(@+ e# Take out the first and last 4 bit group and join
e# them together to get the XOR Hash H
2b\ e# Convert H to decimal form and swap to put the
e# remaining converted input array on top
:+8/ e# Join all bits together and split into groups of 8
2fb e# Convert each 8 but group to decimal form
\f^ e# Swap to put H on top and XOR each number with H
:c e# Get character from each of the ASCII value
답변
Pyth, 69 바이트
Ksm>+0jCd16_2zJ?,hKeKQmxFdCcK2=KsmmxFkC,dJc?tPKQK2smCid16c?KQ++hJKeJ2
이것은 암호화와 암호 해독을 결합하고 단순히 0
암호화 또는 1
해독을위한 인수로 추가합니다 . 그 이유는 간단합니다. 문자열을 비트 (또는 4 비트 정수)로 변환하거나 그 반대는 실제로 Pyth에서 실제로 길다. 두 기능을 하나의 프로그램으로 결합함으로써 많은 바이트를 절약 할 수 있습니다.
설명:
첫 번째 부분은 입력을 4 비트 정수 목록으로 변환하고 (각 문자는 2 개의 4 비트 정수로 변환 됨) 저장합니다 K
.
m z map each character d of input (=z) to:
Cd the ascii-value of d
j 16 convert the result into base 16
>+0 _2 insert a zero to the front and take the last 2 values
(so that each char gets mapped to exactly 2 numbers)
Ks chain all these tuples and assign them to K
두 번째 부분은 해시 값을 결정하여에 저장합니다 J
. 경우 Q==0
는 XOR하여 그들을 계산, 그렇지 않으면의 처음과 마지막 값을 사용합니다 K
.
? Q ... if Q (=second input) else ...
,hKeK [K[0], K[-1]]
m CcK2 map each d of zipped(K chopped into pairs) to:
[zipped(...) gives me 2 lists, one with the values of the even indices, and one with the odd indices]
xFd fold the list d by xor
J store the result in J (this is the hash value)
다음 부분은 해시 값을 사용하여 xor를 수행합니다. Q == 0
전체 목록 K
에서 수행 될 때 , 그렇지 않으면 K
첫 번째 및 마지막 값이없는 목록에서만 수행됩니다 .
=KsmmxFkC,dJc?tPKQK2
?tPKQK K[1:-1] if Q else K
m c 2 map each d of [... chopped into pairs] to:
m C,dJ map each pair k of zip(d,J) to:
xFk apply xor to the 2 values in k
=Ks chain all these tuples and assign them to K
그리고 마지막 부분은 K
다시 문자 로 변환 됩니다.
smCid16c?KQ++hJKeJ2
?KQ++hJKeJ K if Q else J[0] + K + J[1]
m c 2 map each pair of [... chopped into pairs] to:
id16 convert d into a single integer
C convert to char
s join all chars and print
답변
자바 스크립트 ( ES6 ) 83 + 73 = 156
두 함수 모두 바이트를 나타내는 숫자 배열로 입력을 받아서 출력합니다.
암호화 85 84 83
E=s=>s.concat((h=s.reduce((x,y)=>x^y))<<4&240^h).map(x=>a<<4&240|(a=x^h)>>4,a=h>>4)
해독 75 73
D=s=>s.map(x=>(a<<4&240|(a=x)>>4)^h,h=(a=s.shift())&240|s[~-s.length]&15)
데모 (Firefox 만 해당)
E=s=>s.concat((h=s.reduce((x,y)=>x^y))<<4&240^h).map(x=>a<<4&240|(a=x^h)>>4,a=h>>4)
D=s=>s.map(x=>(a<<4&240|(a=x)>>4)^h,h=(a=s.shift())&240|s[~-s.length]&15)
toHexString = x=>'0x'+x.map(y=>y.toString(16)).join('')
input = [...'G0lf'].map(x=>x.charCodeAt());
document.write('Input: ' + toHexString(input) + '<br />');
encrypted = E(input);
document.write('Encrypted: ' + toHexString(encrypted) + '<br />');
decrypted = D(encrypted);
document.write('Decrypted: ' + toHexString(decrypted) + '<br />');
문자열 사용 131 + 129 = 260
그리고 그냥 재미를 위해 … 대신 입출력을 위해 문자열을 사용하는 일부 버전이 있습니다.
E=(s,h=0)=>[for(x of s)(h^=y=x.charCodeAt(),y)].concat(h<<4&240^h).map(x=>String.fromCharCode(a<<4&240|(a=x^h)>>4),a=h>>4).join('')
D=s=>(s=[s.charCodeAt(j=i)for(i in s)]).map(x=>String.fromCharCode((a<<4&240|(a=x)>>4)^h),h=(a=s.shift())&240|s[~-j]&15).join('')
E('G0lf') // 's¤Ñ\x11½'
D('s¤Ñ\x11½') // 'G0lf'