簡體   English   中英

Rot13和使用模數

[英]Rot13 and the use of the modulo

我一直在閱讀Allen B. Downey的“ Think Python”,其中有一個練習(8.12),作者要求創建ROT13函數。 我做了我的,並且部分奏效了,因為我在用大寫字母掙扎。

這是作者提供的解決方案的一部分:

def rotate_letter(letter, n):
"""Rotates a letter by n places.  Does not change other chars.

letter: single-letter string
n: int

Returns: single-letter string
"""
if letter.isupper():
    start = ord('A')
elif letter.islower():
    start = ord('a')
else:
    return letter

c = ord(letter) - start
i = (c + n) % 26 + start
return chr(i)

此處使用模數使該函數適用於大寫字母,但我不知道為什么! 顯然,通過使用它,我們以大寫的ASCII值的開頭重新啟動,但是我無法弄清楚其背后的機制。

嘗試將其分解為多個步驟,然后打印出中間數字。 或者,最好在聯機可視化工具中運行它。

例如,使用字母'Q'和數字13,您將得到:

'Q'.isupper() is true
start = ord('A') = 65
c = ord('Q') - start = 81 - 65 = 16
i = (c + n) % 26 + start = (16 + 13) % 26 + 65 = 29 % 26 + 65 = 3 + 65 = 68
chr(i) is 'D'

如您所見,最神奇的部分是(16 + 13) % 26 因此,讓我們嘗試在從0(對於A )到25(對於Z )的每個數字上運行它,然后看看會發生什么:

>>> for i in range(26):
...     print ((i + 13) % 26),
13 14 15 16 17 18 19 20 21 22 23 24 25 0 1 2 3 4 5 6 7 8 9 10 11 12

加法,然后將余數乘以26,則意味着當您達到26時,您將回到零。就像將1小時加到23:00會使您在時鍾上達到00:00(或者,如果您是美國人,則將1小時加到12:00會使您達到1:00)。

模26本身與大寫和小寫無關,需要使序列回繞到開頭。

考慮一個簡單的“ rot 1”:將字母視為從1到26的數字,然后加1。如果輸入為'a',則取1 + 1 = 2並得到'b';如果輸入為'a',則取1 + 1 = 2。 如果輸入為“ z”,則取26 + 1 = 27-但是沒有27個字母! 因此,您計算出27 mod 26 = 1,它將“旋轉”回'a'。

在上面的實現中,大小寫的實際技巧是start的定義,該定義在應用旋轉之前將ASCII位置轉換為數字1到26,然后使用相同的偏移量將結果返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM