在 abc 范围内将移位的 ASCII 值转换为 char

Convert a shifted ASCII value to char inside the abc scope

背景

这个问题的灵感来自凯撒密码。给定修改后的 ASCII 值 i,其中 i > 122 or i < 97,目标是找到由其值表示的字符。例如,由于 'z' 值为 122,因此 123 引用 'a',以及 14997 +- 26n.

目标

函数 calc_chr 应该计算移位的 ASCII 值,同时保持在 abc 的范围内,即 [97, 122] 十进制。

清楚的例子

'x'120
new_val'x' + 5 -->125
calc_chr(new_val) 等于 'c'

函数 returns 'c',移位 'x' 5 次的结果:x -> y, z, a, b, c.

解决方法

解决方法效率不高。

while new_val > 122:
    new_val -= 26
while new_val < 97:
    new_val += 26

所需的解决方案(如果存在)是一个计算(而非循环)。

不太清楚你到底想做什么。我的理解是你想输入一个人造数字,然后将其转换为 97 到 122(均包含在区间内)。

最简单的方法是:

number = input('Your number: ')
mod_number = ((number - 97) % 26) + 97
print(number, chr(number))

这样你输入一个数字,如果它包含在 97 到 122 之间,那么它将被保留。否则它将被移动到那个区间。因此,如果您输入 123,您将得到 97,如果您输入 96,您将得到 122。

您需要以下 ASCII 映射:

                            a-z
0-18, 19-44, 45-70, 71-96, 97-122, 123-148, 149-174, 175-200, 201-226, 227-252, 253-255
h-z    a-z    a-z    a-z    a-z      a-z      a-z      a-z      a-z      a-z      a-c

\--------- 1 -------------------/
                           \---------------------------- 2 ---------------------------/

对于大多数编程语言(余数的符号是​​被除数的符号),可以使用两个不同的公式:

  1. 对于 0 到 122 范围内的所有数字,使用:

     r = 122 - ((122 - n) % 26)
    
  2. 对于 97 到 255 范围内的所有数字,使用:

     r = ((n - 97) % 26) + 97
    

但是,因为如果我们将除数的倍数加到被除数上,余数不会改变,所以我们可以加上 4 乘以 26,而不必完全处理负被除数。

    r = ((n - 97) % 26) + 97
 => r = ((n - 97 + (4 * 26)) % 26) + 97
<=> r = ((n - 97 + 104) % 26) + 97
<=> r = ((n + 7) % 26) + 97       ; This will work no matter how '%' functions

现在 Python,因为 how the % operator functions,我们可以用这个公式:

r = ((n - 97) % 26) + 97

一个非常快的替代方法定义了一个256字节的数组,然后使用计算出的数字作为这个数组中的偏移量,立即获取结果。

下面是它在汇编 (MASM) 中的样子:

; On input AL register is number n=[0,255]
mov bx, offset array
xlatb
; On output AL register is number r=[97,122]         ; ["a","z"]

...

array db 'hijklmnopqrstuvwxyz'
      db 9 dup ('abcdefghijklmnopqrstuvwxyz')
      db 'abc'

并且在 Python 中变为

s[n]

with n 范围从 0 到 255 并使用 256 字节的字符串 s

s = ("hijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abcdefghijklmnopqrstuvwxyz"
     "abc"
    )