【问题标题】:Python3 replace ord() and chr()Python3 替换 ord() 和 chr()
【发布时间】:2020-09-20 04:00:24
【问题描述】:
        for i in word:
            c = ord(i) - int(key)
            if c < 97:
                c = c + 26
            b = chr(c)
            text += b

没有ord() 和chr() 有没有其他方法可以替换它?

非常感谢!

【问题讨论】:

  • ord() 和 chr() 内置在 python 中。更换它们的具体原因是什么?
  • 您可以预先计算从源字符到目标字符的映射(使用字典),并使用此字典从单词中逐个替换字符。
  • 如果有特殊原因省略 chr/ord,例如一些学校任务,然后您也可以使用bs = word.encode('utf-16') 将字符串转换为字节,然后更改一些字节并使用word = bs.decode('utf-16') 转换回字符串。
  • 并在循环前将key 设为int

标签: python-3.x chr ord


【解决方案1】:

这是使用numpy 模块加上UTF-32 编码/解码的代码。此代码对于大数据将非常快,并且不需要 Python 循环。

numpy 模块可以使用python -m pip install numpy 轻松安装。如果您需要没有 numpy 的解决方案,使用纯 Python,并且运行速度不是问题,请告诉我,我会重写,但纯 Python 代码在大数据上的运行速度会慢得多。

你也可以run this code online here

# Needs: python -m pip install numpy
import numpy as np

word = 'Duck'
key = 1

a = np.frombuffer(word.encode('utf-32-le'), dtype = np.int32)
a = a - key
a[a < 97] += 26

text = a.tobytes().decode('utf-32-le')

print(text)

还有类似的较慢的下一个解决方案,但没有numpy,只使用标准Python 的内置模块struct。你也可以run next code online

import struct

word = 'Duck'
key = 1

text = ''

for i in word:
    c = struct.unpack('<I', i.encode('utf-32-le'))[0] - int(key)
    if c < 97:
        c = c + 26
    b = struct.pack('<I', c).decode('utf-32-le')
    text += b
    
print(text)

下面的另一个解决方案不使用任何模块。 Run next code online.

word = 'Duck'
key = 1

text = ''

for i in word:
    c = int(i.encode('utf-32-be').hex(), 16) - int(key)
    if c < 97:
        c = c + 26
    b = bytes.fromhex(hex(c)[2:].zfill(8)).decode('utf-32-be')
    text += b
    
print(text)

如果文本符号仅来自 ASCII 集合,则代码可以进一步简化 (run this code online):

word = 'Duck'
key = 1

text = ''

for i in word:
    c = i.encode('ascii')[0] - int(key)
    if c < 97:
        c = c + 26
    b = bytes((c,)).decode('ascii')
    text += b
    
print(text)

另一种解决 ASCII 字符情况的方法,使用两个表 (run this code online)

word = 'Duck'
key = 1

tmp = [(c, i) for i, c in enumerate(bytes(range(128)).decode('ascii'))]
c2i = dict(tmp)
i2c = [e[0] for e in tmp]

text = ''

for i in word:
    c = c2i[i] - int(key)
    if c < 97:
        c = c + 26
    b = i2c[c]
    text += b
    
print(text)

通过替换下一行 (run this code online),可以将以前的代码从 ASCII 扩展到更宽的字符集(例如 16 位):

tmp = [(bytes.fromhex(hex(i)[2:].zfill(8)).decode('utf-32-be', 'replace'), i) for i in range(1 << 16)]

【讨论】:

  • 请详细说明。使用struct的原因是什么?
  • @Pynchia 使用 struct 的原因是由于提问者要求不使用 ord/chr,因此 encode/decode + struct unpack/pack 是 ord/chr 的替代品。
  • 也许有一种更简单的方法可以将 4 个字节转换为 int 并返回,而不是 struct
  • 我也可以使用int(bytes_.hex(), 16)
  • 添加了没有任何模块的解决方案。
猜你喜欢
  • 2012-08-30
  • 2012-04-13
  • 2022-12-04
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
相关资源
最近更新 更多