Shifty XORyption


15

Viết chương trình hoặc chức năng (hoặc bộ chương trình / chức năng) để mã hóa và giải mã dữ liệu theo thông số kỹ thuật sau:

Mã hóa

  1. Tính toán hàm băm XOR của đầu vào bằng XOR-ing mỗi byte với nhau.

  2. XOR mỗi byte của đầu vào bởi hàm băm này.

  3. Thay đổi kết quả bốn bit còn lại.

  4. Pad bên trái với bốn bit đầu tiên của hàm băm XOR.

  5. Pad bên phải với bốn bit cuối cùng của hàm băm XOR.

Thí dụ

  • Cho đầu vào: "G0lf"( 0x47306C66)

  • Tính toán băm XOR: 0x47 ^ 0x30 ^ 0x6C ^ 0x66 = 0x7D

  • XOR mỗi byte theo hàm băm: 0x3A4D111B

  • Kết quả dự kiến ​​(sau ca và pad): "s¤Ñ\x11½"( 0x73A4D111BD)

Quy tắc

  • Chương trình / chức năng của bạn có thể nhập / xuất bất kỳ loại nào có ý nghĩa trong ngôn ngữ chơi gôn của bạn (Chuỗi, Mảng Byte, v.v.) miễn là đầu vào / đầu ra là các byte thực tế. Ví dụ: bạn không thể xuất chuỗi thập lục phân.

  • Mã hóa và giải mã có thể được tách thành các chương trình riêng biệt (điểm sẽ là kích thước kết hợp của chúng) hoặc một kích thước duy nhất. Các phương thức đơn lẻ có thể đưa ra một đối số cho việc nó nên mã hóa hay giải mã.

  • Đầu vào để mã hóa có thể được dự kiến ​​có kích thước tối thiểu 1 byte.

  • Đầu vào để giải mã có thể được dự kiến ​​ít nhất là 2 byte.

  • Các byte không in được không cần phải thoát trong đầu ra.


1
Một mảng thập phân có thể được sử dụng như một hình thức đầu ra?
17:30

@ ıʇɥʇuʎs Có thể chấp nhận lấy đầu vào và đầu ra dưới dạng một mảng các số nguyên để biểu diễn các byte.
nderscore

Có độ dài đầu vào tối đa (ví dụ: 14 byte (56 bit), để kết quả cuối cùng phù hợp với số nguyên 64 bit) không?
Doorknob

1
Chỉ cần một lưu ý: Từ quan điểm mật mã, đây không phải là mã hóa, vì nó không có khóa (hoặc khóa 0 bit).
Paŭlo Ebermann

1
Tôi chỉ chờ đợi ai đó đăng một cái gì đó về việc không bao giờ tự mã hóa, bỏ qua trang web này trên ...
user253751

Câu trả lời:


9

CJam, 28 + 27 = 55 byte

Đối với mỗi phần tôi đang trình bày một chương trình dự kiến ​​đầu vào / đầu ra ở dạng một mảng số nguyên và một chương trình sử dụng một chuỗi. Số byte trên dành cho phiên bản mảng số nguyên, nhưng tập lệnh được liên kết và giải thích dành cho phiên bản dựa trên chuỗi (có thể được sử dụng để kiểm tra ví dụ được đưa ra trong câu hỏi).

Mã hóa

q~_:^_GbYUe[\@f^Gfbe_*2/Gfbp
q:i_:^_GbYUe[\@f^Gfbe_*2/Gfb:c

Giải mã

q~{_G/\G%}%)\(G*@+\2/Gfbf^p
q:i{_G/\G%}%)\(G*@+\2/Gfbf^:c

Đây là một kịch bản thử nghiệm thực hiện một chuyến đi khứ hồi đầy đủ và in mã được mã hóa trước khi thực hiện lại quá trình giải mã.

Giải trình

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.

6

CJam, 36 + 34 = 70 byte

Một cách tiếp cận khác nhau bằng cách sử dụng các hình thức nhị phân

Bộ mã hóa :

q_:^:Hf^H+{i2b8Ue[}%)4/~@\]e_8/2fb:c

Làm thế nào nó hoạt động:

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

Bộ giải mã :

q{i2b8Ue[4/~}%)\(@+2b\:+8/2fb\f^:c

Làm thế nào nó hoạt động:

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

Hãy thử mã hóagiải mã trực tuyến


6

Bình thường, 69 byte

Ksm>+0jCd16_2zJ?,hKeKQmxFdCcK2=KsmmxFkC,dJc?tPKQK2smCid16c?KQ++hJKeJ2

Điều này kết hợp mã hóa và giải mã, chỉ cần thêm một 0 như là đối số để mã hóa hoặc 1giải mã. Lý do cho điều này là đơn giản. Chuyển đổi chuỗi thành bit (hoặc số nguyên 4 bit) hoặc ngược lại thực sự rất dài trong Pyth. Bằng cách kết hợp cả hai chức năng vào một chương trình, tôi có thể tiết kiệm được rất nhiều byte.

Trình diễn trực tuyến: Mã hóa và giải .

Giải trình:

Phần đầu tiên chuyển đổi đầu vào thành một danh sách các số nguyên 4 bit (mỗi char được chuyển đổi thành 2 số nguyên 4 bit) và lưu trữ nó vào 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

Phần thứ hai xác định các giá trị băm và lưu trữ chúng trong J. Nếu Q==0nó tính toán chúng bằng xor, nếu không, nó sẽ lấy giá trị đầu tiên và cuối cùng của 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)

Phần tiếp theo thực hiện xor bằng cách sử dụng các giá trị băm. Khi Q == 0nó được thực hiện trên danh sách đầy đủ K, nếu không thì chỉ có trong danh sách Kmà không có giá trị đầu tiên và cuối cùng.

=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

Và phần cuối cùng chuyển đổi Kthành ký tự:

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

0

Javascript ( ES6 ) 83 + 73 = 156

Cả hai hàm đều lấy đầu vào là và xuất ra một mảng các số để biểu diễn các byte.

Mã hóa 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)

Giải mã 75 73

D=s=>s.map(x=>(a<<4&240|(a=x)>>4)^h,h=(a=s.shift())&240|s[~-s.length]&15)

Trình diễn (chỉ dành cho 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 />');


Sử dụng Chuỗi 131 + 129 = 260

Và chỉ để giải trí ... đây là một số phiên bản sử dụng chuỗi cho đầu vào / đầu ra thay thế.

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'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.