XORyption Shifty

15

Tulis program atau fungsi (atau set program / fungsi) untuk mengenkripsi dan mendekripsi data dengan spesifikasi sebagai berikut:

Enkripsi

  1. Hitung hash XOR dari input dengan XOR-ing setiap byte satu sama lain.

  2. XOR setiap byte input oleh hash ini.

  3. Geser hasil empat bit ke kiri.

  4. Pad sisi kiri dengan empat bit pertama hash XOR.

  5. Pad sisi kanan dengan empat bit terakhir hash XOR.

Contoh

  • Masukan yang diberikan: "G0lf"( 0x47306C66)

  • Hitung hash XOR: 0x47 ^ 0x30 ^ 0x6C ^ 0x66 = 0x7D

  • XOR setiap byte oleh hash: 0x3A4D111B

  • Hasil yang diharapkan (setelah shift dan pad): "s¤Ñ\x11½"( 0x73A4D111BD)

Aturan

  • Program / fungsi Anda dapat input / output dari jenis apa pun yang masuk akal dalam bahasa pilihan golf Anda (String, Byte Array, dll) selama input / output adalah byte yang sebenarnya. Misalnya, Anda tidak dapat menghasilkan string heksidecimal.

  • Enkripsi dan dekripsi dapat dipisahkan menjadi program yang terpisah (skor akan menjadi ukuran gabungan mereka) atau satu. Metode tunggal dapat mengambil argumen apakah itu harus mengenkripsi atau mendekripsi.

  • Input untuk enkripsi bisa berukuran minimal 1 byte.

  • Input untuk dekripsi diharapkan minimal 2 byte.

  • Bytes yang tidak dapat dicetak tidak perlu diloloskan dalam output.

nderscore
sumber
1
Bisakah array desimal digunakan sebagai bentuk output?
ɐɔıʇǝɥʇu
@ ɐɔıʇɥʇuʎs Akan dapat diterima untuk mengambil input dan output sebagai array bilangan bulat untuk mewakili byte.
nderscore
Apakah ada panjang input maksimum (misalnya, 14 byte (56 bit), sehingga hasil akhirnya cocok dengan integer 64-bit)?
Gagang Pintu
1
Hanya sebuah catatan: Dari sudut pandang kriptografi, ini bukan enkripsi, karena tidak memiliki kunci (atau kunci 0-bit).
Paŭlo Ebermann
1
Saya hanya menunggu seseorang untuk memposting sesuatu tentang tidak pernah menggulung enkripsi Anda sendiri, mengabaikan situs ini pada ...
user253751

Jawaban:

9

CJam, 28 + 27 = 55 byte

Untuk setiap bagian saya menyajikan satu program yang mengharapkan input / output dalam bentuk array integer dan yang menggunakan string. Hitungan byte di atas adalah untuk versi array integer, tetapi skrip yang ditautkan dan penjelasannya adalah untuk versi berbasis string (yang dapat digunakan untuk menguji contoh yang diberikan dalam pertanyaan).

Enkripsi

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

Dekripsi

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

Ini skrip uji yang melakukan perjalanan penuh dan mencetak kode terenkripsi sebelum melakukan dekripsi lagi.

Penjelasan

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.
Martin Ender
sumber
6

CJam, 36 + 34 = 70 byte

Pendekatan yang sedikit berbeda menggunakan bentuk biner

Encrypter :

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

Bagaimana itu bekerja:

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

Decrypter :

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

Bagaimana itu bekerja:

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

Coba enkripsi dan decrypter online

Pengoptimal
sumber
6

Pyth, 69 byte

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

Ini menggabungkan enkripsi dan dekripsi, cukup tambahkan 0argumen as untuk enkripsi atau 1untuk dekripsi. Alasannya sederhana. Mengubah string menjadi bit (atau 4 bit integer) atau sebaliknya benar-benar panjang di Pyth. Dengan menggabungkan kedua fungsi menjadi satu program, saya dapat menyimpan banyak byte.

Demonstrasi online: Enkripsi dan Dekripsi .

Penjelasan:

Bagian pertama mengubah input menjadi daftar integer 4-bit (setiap karakter dapat dikonversi menjadi 2 integer 4-bit) dan menyimpannya di 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

Bagian kedua menentukan nilai hash dan menyimpannya di J. Jika Q==0ia menghitungnya dengan xor, jika tidak maka akan mengambil nilai pertama dan terakhir dari 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)

Bagian selanjutnya melakukan xor menggunakan nilai hash. Ketika Q == 0itu dilakukan pada daftar lengkap K, jika tidak hanya pada daftar Ktanpa nilai pertama dan terakhir.

=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

Dan bagian terakhir mengkonversi Kkembali ke karakter:

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
Jakube
sumber
0

Javascript ( ES6 ) 83 + 73 = 156

Kedua fungsi mengambil input sebagai dan ouput array angka untuk mewakili byte.

Enkripsi 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)

Dekripsi 75 73

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

Demonstrasi (khusus 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 />');


Menggunakan String 131 + 129 = 260

Dan hanya untuk bersenang-senang ... inilah beberapa versi yang menggunakan string untuk input / output sebagai gantinya.

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'
nderscore
sumber