XORyption ที่มีเล่ห์เหลี่ยม


15

เขียนโปรแกรมหรือฟังก์ชั่น (หรือชุดของโปรแกรม / ฟังก์ชั่น) เพื่อเข้ารหัสและถอดรหัสข้อมูลตามข้อกำหนดต่อไปนี้:

การเข้ารหัสลับ

  1. คำนวณแฮช XOR ของอินพุตโดย XOR-ing ทุกไบต์พร้อม ๆ กัน

  2. แฮคเกอร์ทุกไบต์ของอินพุทโดยแฮชนี้

  3. เลื่อนผลลัพธ์ไปทางซ้ายสี่บิต

  4. วางด้านซ้ายด้วยแฮชสี่บิตแรกของแฮช

  5. วางด้านขวาด้วยแฮช XOR สี่บิตสุดท้าย

ตัวอย่าง

  • อินพุตที่ได้รับ: "G0lf"( 0x47306C66)

  • คำนวณแฮช XOR: 0x47 ^ 0x30 ^ 0x6C ^ 0x66 = 0x7D

  • แฮคเกอร์ทุกไบต์โดยแฮ: 0x3A4D111B

  • ผลลัพธ์ที่คาดหวัง (หลังเปลี่ยนและเบาะ): "s¤Ñ\x11½"( 0x73A4D111BD)

กฎระเบียบ

  • โปรแกรม / ฟังก์ชั่นของคุณสามารถอินพุต / เอาต์พุตชนิดใดก็ได้ที่เหมาะสมกับภาษากอล์ฟที่คุณเลือก(String, Byte Array, ฯลฯ )ตราบใดที่อินพุต / เอาท์พุตเป็นไบต์จริง ตัวอย่างเช่นคุณไม่สามารถส่งออกสตริงเลขฐานสิบหก

  • การเข้ารหัสและถอดรหัสสามารถแยกออกเป็นโปรแกรมแยกต่างหาก (คะแนนจะเป็นขนาดรวมกัน) หรือขนาดเดียว วิธีการเดี่ยวสามารถโต้แย้งว่าควรจะเข้ารหัสหรือถอดรหัส

  • อินพุตสำหรับการเข้ารหัสสามารถคาดว่ามีขนาดอย่างน้อย 1 ไบต์

  • อินพุตสำหรับถอดรหัสสามารถคาดว่าจะมีอย่างน้อย 2 ไบต์

  • ไม่สามารถพิมพ์ไบต์ที่ไม่สามารถพิมพ์ได้ในเอาต์พุต


1
สามารถใช้อาร์เรย์ทศนิยมเป็นรูปแบบผลลัพธ์ได้หรือไม่
Aprıʇǝɥʇuʎs

@ ɐɔıʇɥʇuʎsจะสามารถรับอินพุตและเอาต์พุตเป็นอาร์เรย์จำนวนเต็มเพื่อแทนค่าไบต์ได้
nderscore

มีความยาวอินพุตสูงสุด (ตัวอย่างเช่น 14 ไบต์ (56 บิต) ดังนั้นผลลัพธ์สุดท้ายควรเป็นจำนวนเต็ม 64 บิต) หรือไม่
Doorknob

1
เพียงหมายเหตุ: จากมุมมองการเข้ารหัสนี้ไม่ใช่การเข้ารหัสเนื่องจากไม่มีคีย์ (หรือคีย์ 0 บิต)
Paŭlo Ebermann

1
ฉันแค่รอให้ใครบางคนโพสต์บางสิ่งบางอย่างเกี่ยวกับไม่เคยกลิ้งการเข้ารหัสของคุณโดยไม่สนใจเว็บไซต์ที่อยู่ใน ...
user253751

คำตอบ:


9

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.

6

CJam, 36 + 34 = 70 ไบต์

วิธีที่แตกต่างกันเล็กน้อยโดยใช้รูปแบบไบนารี

Encrypter :

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

Decrypter :

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

ลองencrypterและdecrypterออนไลน์


6

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

0

Javascript ( 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'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.