Dec 3, 2010

Cryptography ตอนที่ 5 การเข้ารหัสลับวิจเญอแนร์

เราจะเห็นว่าการเข้ารหัสลับในสามตอนที่ผ่านมานั้น จะจับคู่จากอักษรไปยังอักษรตัวเดิมเสมอ
ซึ่งนั่นส่งผลให้เราใช้วิธีง่ายๆ คือไล่แทนอักษรไปเรื่อยๆ (brute force) ได้ แม้ว่ามันจะกินเวลาก็ตาม
เราเรียกวิธีเข้ารหัสจากทั้งสามตอนนั้นว่าเป็นแบบ monoalphabetic หรือแบบอักษรตายตัวครับ

ในปี 1553 จึงได้มีการคิดค้นวิธีเข้ารหัสลับแบบ polyalphabetic หรือแบบอักษรไม่ตายตัวขึ้น
ผู้คิดค้นคือ Giovan Battista Bellaso แต่เนื่องด้วยเหตุผลทางประวัติศาสตร์ในช่วงศตวรรษที่ 19
ทำให้ผู้ที่ได้รับเครดิทกลายเป็น Blaise de Vigen?re แทน เราจึงรู้จักวิธีนี้ในชื่อ Vigen?re Cipher

ข้อดีของการเข้ารหัสลับด้วยวิธีนี้คือ เข้ารหัสง่าย แต่โจมตีรหัสยาก (อย่างน้อยถ้าไม่มีคอมฯ)
ขั้นตอนการเข้ารหัสก็ง่ายเหลือหลายอย่างที่ว่ามา แค่เลือกชุดตัวเลขที่จะใช้เป็นกุญแจมาชุดหนึ่ง
แล้วก็เอาอักษรตัวแรกบวกกับเลขในกุญแจอันแรก อักษรตัวที่สองบวกเลขตัวที่สองไปเรื่อยๆ
จนเมื่อชุดตัวเลขในกุญแจที่ใช้หมด ก็กลับไปเริ่มเลขตัวแรกในกุญแจใหม่อีกครั้ง
ง่ายจริงๆ ให้ดินตายเลย (งั้นไปดูคณิตศาสตร์ก่อนที่จะดิ้นตายดีกว่า 555+)

ให้ P = C = Z26 และให้ K = {(a1, a2, a3, ... , ai) ใน Z26 สำหรับ i ใน N}
สำหรับ K = (a1, a2, a3, ... , ai) สร้าง K* = (a1, a2, a3, ... , ai, a1, ...) และกล่าวว่า
eK(x) = (xj + aj) mod 26 และ dK(y) = (yj - aj) mod 26
สำหรับ x, y ที่เป็นสมาชิกของ Z26 และ aj ที่เป็นสมาชิกของ K*

สำหรับนักคณิตศาสตร์แล้ว จะแปลงกุญแจจากสั้นๆ ให้เป็นอนันต์ก่อน แล้วจึงค่อยนำกุญแจไปใช้
จะเห็นว่าวิธีนี้ key space ใหญ่ขึ้นอย่างรวดเร็ว เพียงแค่เพิ่มตัวเลขในกุญแจ ซึ่งคือ 26i นั่นเอง
เลขในกุญแจเพียงแค่ 5 ตัวจะสร้าง key space ที่ใหญ่ถึง 255 = 11.8 x 106 เลยครับ

นอกจากนี้ก็ไม่มีอะไรยากแล้ว ไปเอาโค้ดการเข้ารหัสลับแบบเลื่อนมาแก้ไขนิดเดียวก็ใช้ได้แล้วครับ

บรรทัด 1 เปลี่ยนชื่อ และเปลี่ยนเงื่อนไขการใช้กุญแจจากแบบเลขตัวเดียว เป็นลิสต์เลขหลายตัว
บรรทัด 5 เปลี่ยน logic ของการคำนวน คือให้ใช้เลขในกุญแจตามลำดับที่เปลี่ยนไปเรื่อยๆ

def vigenere(pain_text, key_list):
cipher_text = ""
for i in range(len(pain_text)):
char_num = lower_to_number(pain_text[i])
char_num += key_list[i%len(key_list)]
char_num %= 26
cipher_text += number_to_upper(char_num)
return(cipher_text)


จะเห็นว่า ทางคอมพิวเตอร์นั้น เราไม่จำเป็นต้องสร้าง K* เหมือนทางคณิตศาสตร์ก็ได้
แต่จะใช้ modulo เพื่อวนเรียกใช้เลขที่เราต้องการเมื่อเราใช้เลขในลิสต์หมดครับ
อ๋อ เวลาเรียกฟังก์ชันนี้ขึ้นมาใช้ ตัวแปรด้านหลังต้องพิมพ์เป็นตัวแปรแบบลิสต์อย่างนี้นะครับ

>>> encrypt.vigenere("testvigenerecipher", [4, 25, 7, 12, 0]) 


ส่วนผลลัพท์จะออกมาเป็นอย่างไร ต้องฝากเป็นการบ้านไว้พร้อมกับการเขียน decrypt ครับ
เจอกันคราวหน้าครับ ^__^