ปัญหาการเข้ารหัส/ถอดรหัสตามการหมุนเวียนพื้นฐาน

โดยพื้นฐานแล้ว ฉันกำลังติดตามโปรแกรม Encryptor ที่ท้าทายของห้องทดลอง Jumpstart และพบปัญหาบางประการ

นี่คือรหัสของฉัน

class Encryptor
  def cipher(rotation)
    characters = (' '..'z').to_a
    rotated_characters = characters.rotate(rotation)
    Hash[characters.zip(rotated_characters)]
  end

  def encrypt_letter(letter, rotation)
    cipher_for_rotation = cipher(rotation)
    cipher_for_rotation[letter]
  end

  def encrypt(string, rotation)
    letters = string.split("")

    results = letters.collect do |letter|
        encrypt_letter = encrypt_letter(letter, rotation)
    end

    results.join
  end

  def decrypt_letter(letter, rotation)
    cipher_for_rotation = cipher(rotation)
    reversed_cipher = cipher_for_rotation.to_a.reverse.to_h
    reversed_cipher[letter]
  end

  def decrypt(string, rotation)
    letters = string.split("")

    results = letters.collect do |letter|
        decrypt_letter = decrypt_letter(letter, rotation)
    end

    results.join
  end
end

ฉันประสบปัญหาเกี่ยวกับวิธีการถอดรหัสของฉัน นี่คือข้อความต่อไปนี้วางจาก irb

2.3.0 :001 > load './encryptor.rb'
 => true
2.3.0 :002 > e = Encryptor.new
 => #<Encryptor:0x007fe93a0319b8>
2.3.0 :003 > encrypted = e.encrypt("Hello, World!", 10)
 => "Rovvy6*ay!vn+"
2.3.0 :004 > e.decrypt(encrypted, 10)
 => "\\y%%(@4k(+%x5"

อย่างที่คุณเห็น เมื่อถอดรหัสสตริงที่เข้ารหัสของฉัน มันควรจะแสดงข้อความว่า "Hello, World!" ซึ่งเป็นสิ่งที่ฉันเข้ารหัสด้วยการหมุน 10 อย่าเห็นว่าฉันทำอะไรผิดที่นี่ ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม .


person Sam Lim    schedule 21.02.2017    source แหล่งที่มา
comment
มันเป็นปัญหาอย่างแน่นอนกับฟังก์ชัน decrypt_letter ของฉัน ตรวจสอบสิ่งต่อไปนี้หลังจากการดีบักใน irb: e.encrypt_letter('t',13) =› & › e.decrypt_letter('&',13) =› 3   -  person Sam Lim    schedule 21.02.2017
comment
มีวิธีที่ดีกว่าวิธี '.to_a.reverse.to_h' ของฉันหรือไม่   -  person Sam Lim    schedule 21.02.2017
comment
ฉันยอมรับว่าฉันไม่ได้ดูโค้ดของคุณอย่างลึกซึ้ง แต่การที่วิธีการถอดรหัสและการเข้ารหัสของคุณดูแตกต่างออกไปนั้นเป็นสัญญาณอันตรายสำหรับฉัน (อันที่จริง การที่คุณมีสองวิธีนั้นน่าสงสัย) จากสิ่งที่ฉันเข้าใจเกี่ยวกับโค้ดของคุณ คุณกำลังใช้ Caesar Cipher และ Caesar Cipher นั้นมีความสมมาตรอย่างสมบูรณ์: การเข้ารหัสและการถอดรหัสเป็นสิ่งเดียวกันทุกประการ เพียงแค่มีปุ่มที่แตกต่างกัน ไม่ควรมีสองวิธี และ แน่นอน ไม่ควรมีสองวิธีแตกต่างกันสำหรับการเข้ารหัสและการถอดรหัส เนื่องจากทั้งสองวิธีเหมือนกันทุกประการ   -  person Jörg W Mittag    schedule 21.02.2017
comment
@ JörgWMittag ขอบคุณมากสำหรับการตอบกลับ ฉันแค่เข้าใจพื้นฐานของทับทิมที่นี่ ฉันกำลังติดตามบทช่วยสอนนี้: tutorials.jumpstartlab.com/projects/encryptor.html ซึ่งฉันเดาว่าทำให้ฉันใช้วิธีการตามที่คุณพูดถึง แต่แสดงวิธีที่ผิดก่อน? ไม่แน่ใจ. จะรับฟังคำแนะนำของคุณและทำการวิจัยเพิ่มเติมอย่างแน่นอน   -  person Sam Lim    schedule 21.02.2017
comment
โดยพื้นฐานแล้ว decrypt(10) จะเหมือนกับ encrypt(-10) ซึ่งจะเหมือนกับ encrypt(17) (สมมติว่ามีตัวอักษร 27 ตัว) โดยทั่วไปแล้ว decrypt(N) == encrypt(-N) == encrypt(alphabet.size - N)   -  person Jörg W Mittag    schedule 21.02.2017
comment
อีกสิ่งหนึ่งที่ฉันสังเกตเห็น: cipher_for_rotation.to_a.reverse.to_h คุณเปลี่ยนพจนานุกรมให้เป็นอาร์เรย์ ย้อนกลับอาร์เรย์ (เช่น กลับลำดับของพจนานุกรม) แล้วเปลี่ยนให้เป็นพจนานุกรมอีกครั้ง แต่ลำดับไม่สำคัญสำหรับพจนานุกรม ดังนั้นคุณจึงได้พจนานุกรมเดียวกับที่คุณเริ่มใช้ เพื่อให้แม่นยำยิ่งขึ้น: Ruby Hashes do คงลำดับการแทรกของคีย์ไว้ และรับประกันว่าจะวนซ้ำตามลำดับนั้น ดังนั้นสิ่งที่คุณทำคือกลับลำดับการแทรก (และจึงกลับลำดับการวนซ้ำ) แต่คุณไม่เคยวนซ้ำแฮช คุณจะเข้าถึงเฉพาะค่าของมันเท่านั้น   -  person Jörg W Mittag    schedule 21.02.2017
comment
โดยพื้นฐานแล้วมันเป็น NO-OP   -  person Jörg W Mittag    schedule 21.02.2017


คำตอบ (1)


คุณสามารถค้นหาคีย์ของแฮชได้

def decrypt_letter(letter, rotation)
  cipher_for_rotation = cipher(rotation)
  cipher_for_rotation.key(letter)
end

ตัวอย่าง:

irb(main):003:0> e = Encryptor.new
=> #<Encryptor:0x007fbcea9b65c8>
irb(main):004:0> enc = e.encrypt "Hello, World!", 10
=> "Rovvy6*ay!vn+"
irb(main):005:0> e.decrypt enc, 10
=> "Hello, World!"
person rohit89    schedule 21.02.2017
comment
นี่อาจเป็นสิ่งที่ฉันกำลังมองหา ขอบคุณสำหรับข้อมูล ใช่ มันทำงานได้อย่างสมบูรณ์แบบ ขอบคุณมาก - person Sam Lim; 21.02.2017