【问题标题】:Hex string convert to ASCII after XOR十六进制字符串在异或后转换为 ASCII
【发布时间】:2018-08-25 12:42:32
【问题描述】:

我是 Python 新手,我正在尝试学习如何对十六进制编码的密文进行异或运算,然后导出它的 ASCII 值。

我已经尝试过之前关于这个主题的帖子中概述的一些函数 - 例如 bytearray.fromhex、binascii.unhexlify、decode("hex") 并且它们都产生了不同的错误(显然是由于我缺乏理解)。其中一些错误是由于我的 python 版本(python 3)造成的。

让我举一个简单的例子,假设我有一个十六进制编码的字符串 ciphertext_1 ("4A17") 和一个十六进制结束的字符串 ciphertext_2。我想对这两个字符串进行异或运算并得出它们的 ASCII 值。我最接近解决方案的是以下代码:

result=hex(int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
print(result)

这会打印我的结果:0xd07 (这是一个十六进制字符串是我的理解吗??)

然后我尝试将其转换为其 ASCII 值。目前,我正在尝试:

binascii.unhexliy(result)

但是这给了我一个错误:“binascii.Error: Odd-length string” 我已经尝试了上述不同的功能,并尝试解决这个特定的错误(strip 函数给出了另一个错误) - 但是我没有成功。我意识到我缺乏对这个主题的知识和理解,所以我希望有人可以给我建议?

完整示例:

#!/usr/bin/env python
import binascii

ciphertext_1="4A17"
ciphertext_2="4710"

result=hex(int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
print(result)
print(binascii.unhexliy(result))

【问题讨论】:

  • 忘记添加 ciphertext_2 = "4710"
  • 如果您创建Minimal, Complete, and Verifiable 示例,您将获得更多更好的答案。尤其要确保输入和预期的测试数据是完整的(不是伪数据),并且可以很容易地剪切和粘贴到编辑器中,以便测试建议的解决方案。
  • 谢谢斯蒂芬,我刚刚在那里做了。
  • 你没有列出你所期望的。
  • 我可能误解了一些东西,但是 int(result,16) 不起作用吗? (你有一个拼写错误 - 它是 hexlify)

标签: python string hex ascii xor


【解决方案1】:
from binascii import unhexlify

ciphertext_1 = "4A17"
ciphertext_2 = "4710"
xored = (int(ciphertext_1, 16) ^ int(ciphertext_2, 16))
# We format this integer: hex, no leading 0x, uppercase
string = format(xored, 'X')
# We pad it with an initial 0 if the length of the string is odd
if len(string) % 2:
    string = '0' + string
# unexlify returns a bytes object, we decode it to obtain a string
print(unhexlify(string).decode())
#
# Not much appears, just a CR followed by a BELL

或者,如果您更喜欢字符串的repr

print(repr(unhexlify(string).decode()))
# '\r\x07'

【讨论】:

  • 我已经逐字逐句地尝试过了,但是打印并没有打印出任何结果。我希望它打印 '\r\x07'。也许我忽略了什么?
  • \r 是回车符,\x07 是铃铛,因此在打印它们时您不会看到太多(空行,也可能很少,取决于您的终端)。如果要查看字符串的`'\r\x07', you need the repr`:print(repr(unhexlify(string).decode()))
【解决方案2】:

在进行 XOR 之类的逐字节运算时,使用 bytes 对象通常更容易(因为单个字节被视为整数)。从this question,我们得到:

ciphertext_1 = bytes.fromhex("4A17")
ciphertext_2 = bytes.fromhex("4710")

然后可以像在this question 中那样通过理解来完成对字节的异或操作。然后您可以将其转换为字符串:

result = [c1 ^ c2 for (c1, c2) in zip(ciphertext_1, ciphertext_2)]
result = ''.join(chr(c) for c in result)

我可能会采取稍微不同的角度并创建一个bytes 对象而不是一个列表,它可以被解码为您的字符串:

result = bytes(b1 ^ b2 for (b1, b2) in zip(ciphertext_1, ciphertext_2)).decode()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-22
    • 2014-11-16
    • 2011-11-21
    • 2019-07-26
    • 2011-06-14
    • 1970-01-01
    相关资源
    最近更新 更多