Shifty XORyption


15

Scrivi un programma o una funzione (o un insieme di programmi / funzioni) per crittografare e decrittografare i dati in base alle seguenti specifiche:

crittografia

  1. Calcola un hash XOR dell'input XOR-ing ogni byte con l'altro.

  2. XOR ogni byte dell'ingresso da questo hash.

  3. Sposta il risultato di quattro bit rimanenti.

  4. Riempi il lato sinistro con i primi quattro bit dell'hash XOR.

  5. Riempi il lato destro con gli ultimi quattro bit dell'hash XOR.

Esempio

  • Dato input: "G0lf"( 0x47306C66)

  • Calcola l'hash XOR: 0x47 ^ 0x30 ^ 0x6C ^ 0x66 = 0x7D

  • XOR ogni byte per hash: 0x3A4D111B

  • Risultato atteso (dopo shift e pad): "s¤Ñ\x11½"( 0x73A4D111BD)

Regole

  • Il tuo programma / funzione può inserire / emettere qualsiasi tipo abbia senso nella tua lingua di golf preferita (String, Byte Array, ecc.) Fintanto che l'input / output sono i byte effettivi. Ad esempio, non è possibile generare una stringa esadecimale.

  • La crittografia e la decrittografia possono essere separate in programmi separati (il punteggio sarà la loro dimensione combinata) o uno singolo. I singoli metodi possono sostenere un argomento per stabilire se crittografare o decrittografare.

  • Si prevede che l'input per la crittografia abbia una dimensione di almeno 1 byte.

  • È possibile prevedere che l'input per la decrittografia sia di almeno 2 byte.

  • I byte non stampabili non devono essere sottoposti a escape nell'output.


1
È possibile utilizzare una matrice decimale come modulo di output?
Aprıʇǝɥʇuʎs

@ ɐɔıʇɥʇuʎs Sarebbe accettabile prendere input e output come un array di numeri interi per rappresentare byte.
nderscore,

Esiste una lunghezza massima di input (ad esempio 14 byte (56 bit), in modo che il risultato finale si adatti a un numero intero a 64 bit)?
Maniglia della porta

1
Solo una nota: dal punto di vista della crittografia questa non è una crittografia, in quanto non ha chiave (o chiave a 0 bit).
Paŭlo Ebermann,

1
Sto solo aspettando che qualcuno
pubblichi

Risposte:


9

CJam, 28 + 27 = 55 byte

Per ogni parte sto presentando un programma che prevede input / output nella forma di un array intero e uno che utilizza una stringa. Il conteggio di byte sopra è per la versione di array di numeri interi, ma lo script collegato e la spiegazione sono per la versione basata su stringa (che può essere utilizzata per testare l'esempio fornito nella domanda).

crittografia

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

decrittazione

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

Ecco uno script di test che esegue un round trip completo e stampa il codice crittografato prima di ripetere la decodifica.

Spiegazione

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

Un approccio un po 'diverso usando i moduli binari

Encrypter :

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

Come funziona:

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

Decifratore :

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

Come funziona:

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

Prova il codificatore e decodificatore online


6

Pyth, 69 byte

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

Questo combina crittografia e decrittografia, è sufficiente aggiungere un 0argomento as per la crittografia o un 1per la decrittografia. Il motivo è semplice. La conversione di stringhe in bit (o numero intero a 4 bit) o ​​viceversa è davvero molto lunga in Pyth. Combinando entrambe le funzioni in un unico programma, posso salvare molti byte.

Dimostrazioni online: crittografia e decrittografia .

Spiegazione:

La prima parte converte l'input in un elenco di numeri interi a 4 bit (ogni carattere viene convertito in 2 numeri interi a 4 bit) e lo memorizza 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

La seconda parte determina i valori di hash e li memorizza J. Se Q==0li calcola per xor, altrimenti prende il primo e l'ultimo valore di 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)

La parte successiva esegue lo xor usando i valori hash. Quando Q == 0viene eseguito nell'elenco completo K, altrimenti solo nell'elenco Ksenza il primo e l'ultimo valore.

=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

E l'ultima parte si converte Kin caratteri:

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

Entrambe le funzioni accettano input come e generano una matrice di numeri per rappresentare byte.

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

Decrypt 75 73

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

Dimostrazione (solo 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 />');


Utilizzo delle stringhe 131 + 129 = 260

E solo per divertimento ... ecco alcune versioni che usano invece stringhe per input / output.

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'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.