看過《斯巴達克斯》嗎?裡面的反派竟是密碼學鼻祖

若有小夥伴讓你推薦一部暴力、血腥、色情的美劇,很多人可能會推薦《斯巴達克斯》。斯巴達克斯和他的小夥伴們經過不懈的努力,一次又一次戰勝前來鎮壓他們的軍隊,最終還是輸給了克拉蘇、龐培和凱撒。

看過《斯巴達克斯》嗎?裡面的反派竟是密碼學鼻祖

圖1 斯巴達克斯劇照

其實今天想說的是凱撒,因為最近在研究密碼學相關知識,發現凱撒竟然是密碼學鼻祖。據傳,掌管軍隊的他曾創立了凱撒密碼,這種方式當然也是為了加密作戰資訊。凱撒密碼其實很簡單,如下圖2所示。凱撒密碼是採用固定平移的方式,形成一個固定的對應關係,當決定平移為3時,那麼a——D,b——E……以此類推,透過該種方式就可以將訊息加密,對方解密也很容易,只需要按照事先約定好的平移數就可以反過來採用一一對應的方式得到原文。

看過《斯巴達克斯》嗎?裡面的反派竟是密碼學鼻祖

圖2 凱撒密碼示意圖

利用Go語言來實現加密的過程也很容易,只需定義兩個26字母的長字串,然後按照平移位數來計算密文就可以了。參考程式碼如下。

package main

import (

“fmt”

“strings”

var text = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”

var bigtext = “abcdefghijklmnopqrstuvwxyz”

// 加密方法:data是原文,length代表平移位數

func Encode(length int, data string) string {

var result []byte

if length > len(text) {

return “”

}

for _, v := range []byte(data) {

//fmt。Printf(“%d-%c\n”, k, v)

n := strings。IndexByte(bigtext, v) + length

fmt。Println(“n = ”, n)

if n >= 26 {

n = n - 26

}

result = append(result, text[n])

//fmt。Printf(“%c\n”, text[n])

}

fmt。Println(“get:”, string(result))

return string(result)

}

凱撒密碼的解密也很簡單,同樣是按照平移位數來一個反對應就可以了。

// 密文解密:data為密文,length為平移位數

func Decode(data string, length int) string {

var result []byte

if length > len(text) {

return “”

}

for _, v := range []byte(data) {

//fmt。Printf(“%d-%c\n”, k, v)

n := strings。IndexByte(text, v) - length

//fmt。Println(“n = ”, n)

if n < 0 {

n = n + 26

}

result = append(result, bigtext[n])

//fmt。Printf(“%c\n”, text[n])

}

//fmt。Println(“get:”, string(result))

return string(result)

}

最後,可以透過main函式來驗證一下加密和解密的效果。

func main() {

Encode(3, “yekai”)

fmt。Println(Decode(“BHNDL”, 3))

}

執行該程式碼,就可以看到加密和解密後的效果。

凱撒密碼的原理已經瞭解了?如何破解呢?其實很簡單,對於凱撒密碼來說,使用的字典是明確的,唯一的變數是平移位數,因此,我們只要對平移位數進行暴力窮舉,就總能找到答案。

for i := 0; i < 26; i++ {

fmt。Printf(“i = %d, result = %s\n”, i, Decode(“BHNDL”, i))

}

根據上述程式碼打印出來的結果,我們能夠發現當平移位數為3的時候,列印的資訊是:yekai,好像發現這個秘密了!

密碼學在區塊鏈系統中扮演著舉足輕重的作用,如果小夥伴對區塊鏈感興趣,不妨關注公眾號,並留言。葉開老師正在推出一個關於區塊鏈的學習計劃。

看過《斯巴達克斯》嗎?裡面的反派竟是密碼學鼻祖

圖3 參與計劃者可獲葉開老師原創書籍