在 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'
,以及 149
和 97 +- 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 ---------------------------/
对于大多数编程语言(余数的符号是被除数的符号),可以使用两个不同的公式:
对于 0 到 122 范围内的所有数字,使用:
r = 122 - ((122 - n) % 26)
对于 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"
)
背景
这个问题的灵感来自凯撒密码。给定修改后的 ASCII 值 i
,其中 i > 122 or i < 97
,目标是找到由其值表示的字符。例如,由于 'z'
值为 122
,因此 123
引用 'a'
,以及 149
和 97 +- 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 ---------------------------/
对于大多数编程语言(余数的符号是被除数的符号),可以使用两个不同的公式:
对于 0 到 122 范围内的所有数字,使用:
r = 122 - ((122 - n) % 26)
对于 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"
)