我有 2 个介于 0-31 之间的值。我希望能够用 1 个字符表示这两个值(例如以 64 为基数来解释 1 个字符的含义),但仍然能够知道这两个值是什么以及哪个值在先。
最佳答案
找到一个具有 1024 个连续代码点的漂亮 Unicode block ,例如 CJK Unified Ideographs ,并将您的 32*32 值映射到它们上。在 Python 3 中:
def char_encode(a, b):
return chr(0x4E00 + a * 32 + b)
def char_decode(c):
return divmod(ord(c) - 0x4E00, 32)
print(char_encode(17, 3))
# => 倣
print(char_decode('倣'))
# => (17, 3)
正如你提到的 Base64...这是不可能的。 Base64 编码中的每个字符仅允许 6 位数据,您需要 10 位来表示您的两个数字。
还要注意,虽然这只是一个字符,但它会占用两个或三个字节,具体取决于您使用的编码。正如其他人所指出的,无法将 10 位数据填充到 8 位字节中。
解释:a * 32 + b
只是将 [0, 32) 范围内的两个数字映射为 [0, 1024) 范围内的单个数字。例如,0 * 32 + 0 = 0
; 31 * 32 + 31 = 1023
。 chr
查找具有该代码点的 Unicode 字符,但具有低代码点(如 0
)的字符不可打印,并且将是一个糟糕的选择,因此结果被转移到一个漂亮的大 Unicode block 的开头:0x4E00
是 19968
的十六进制表示形式,并且是 CJK 统一表意文字 block 中第一个字符的代码点。使用示例值 17 * 32 + 3 = 547
和 19968 + 547 = 20515
,或十六进制的 0x5023
,它是以下代码点角色仿
。因此,chr(20515) = "仿"
。
char_decode
函数只是反向执行所有这些操作:如果 a * p + b = x
,则 a, b = divmod(x, p)
(参见 divmod
)。如果 c = chr(x)
,则 x = ord(c)
(请参阅 ord
)。我相信您知道,如果 w + r = y
,则 r = y - w
。因此,在示例中,ord("仿") = 20515
; 20515 - 0x4E00 = 547
; divmod(547, 32)
为 (17, 3)
。
关于python - Python中用一个字符表示多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72709926/