ord(p) - ord('a')
這個意思是以 'a' 為序號0,計算字符p的序號。在ASCII字符集中,小寫字母a-z是連續排列的,因此如果a是0的話,那么b就是1,c就是2……以此類推。
ord(p) - ord('a') + 3
前面一段我們解釋過了,那么這一段的意思就是把這個序號+3
(ord(p) - ord('a') + 3) % 26
將序號+3后的結果以26為基數取模。意思就是如果這個數超過26那么就回到0重新循環。也就是說我們讓這個數字始終處于0-25的范圍中。如果這個數是26,那么最終將回到0,27會變成1……以此類推。
ord('a') + ((ord(p) - ord('a') + 3) % 26)
通過后面的一串運算,我們得到了英文字母在字母表所在序號的后三個序號。比如,原字母是b,那么它的原始序號是1,經過運算之后得到4。原字母是x,原始序號是23,經過運算之后得到0。y會得到1。等等。
然后把這個序號再加上'a'字母的字符集編碼,就得到了這個字母的真正字符集編碼。
這里稍微提一下字符集的概念。我們知道計算機是通過0和1形成的二進制來進行數據的表示和運算的。0和1很顯然只能表示數字。如果我們要處理文字、圖像、視頻之類的非數字信息,就需要找到一種方法將它們的信息和數字對應起來,也就是所謂的“數字化”。對于文字,尤其是計算機誕生之初處理的英文信息,我們提供了一種約定,將每一個英文字母和一些符號分配一個數字。以后我們看到這個數字就知道它對應的字符是啥了。ASCII字符集就是早期比較流行的一種通用約定。在這種約定中,'a'對應的數字是97,'b'對應的數字是98……以此類推。反過來說,如果我們從某個地方讀到了一個數字97,并且我們知道我們在讀取一個字符,我們就知道它是字符'a',等等。
現在更流行的字符集是基于UNICODE的UTF-8編碼字符集。這個字符集能表示更多的字符,包括中文。其中的英文部分,跟ASCII字符集幾乎是完全兼容的。
上面那段代碼,實際上就是計算出移位之后的新字符的字符集編碼。
最后我們通過 chr 函數,告知系統這實際上是一個字符。那么print函數就會把編碼對應的字符打印出來。
那么綜合一下,這行代碼的實際意思就是打印原字符后移三個字母之后的新字母(如果序號超過'z'則回到字母表開頭進行循環)。這其實也就是凱撒加密算法的核心了。
舉個例子來說。
hello, worldz 這個字符串,經過處理之后,打印出的應該是:khoor,zrougc