我正在做一些XOR的数据,而且基于我的十六进制XOR的事情进展顺利。建议我使用字节XOR(^)并仅使用字节。我认为这将不会有时间改变,但我有一些我没想到的奇怪行为。
如果我将字符串作为字节处理,有些人可以为我得到不同的结果添加一些亮点。我期待它是一样的。
m_hex_string ="124f33e6a118566377f237075354541f0a5a1b"
m_XOR_string ="662756c6c27732065796586974207468652870"
m_expected ="the code don't work"
m_expected_hex ="74686520636f646520646f6e277420776f726b"
def XOR_hex_strings(a,b)
(a.hex ^ b.hex).to_s(16)
end
def XOR_byte_strings(s1,s2)
xored = s1.bytes.zip(s2.bytes).map { |(a,b)| a ^ b }.pack('c*')
end
def hex_digest(hexdigest)
[hexdigest].pack("H*")
end
puts "My strings for stack overflow"
puts "'"+hex_digest(XOR_hex_strings(m_hex_string,m_XOR_string))+"'"
puts "'"+hex_digest(XOR_byte_strings(m_hex_string,m_XOR_string))+"'"
结果:
My strings for stack overflow
'the code don't work'
'tje`#ode ?on't ~mrk'
对于这两种方法,文本应该是相同的“代码不起作用”。我真的很想知道为什么而不仅仅是一个正确的代码片段。感谢。
答案 0 :(得分:0)
正如评论中已经说过的那样,bytes
不考虑十六进制格式,它只返回"1"
,"2"
,"4"
的整数值, "f"
等。您可以使用pack
转换十六进制字符串:
[m_hex_string].pack("H*")
# => "\x12O3\xE6\xA1\x18Vcw\xF27\aSTT\x1F\nZ\e"
unpack
将此转换为字节数组,就像bytes
一样,但更明确,更快(IIRC):
[m_hex_string].pack("H*").unpack("C*")
# => [18, 79, 51, 230, 161, 24, 86, 99, 119, 242, 55, 7, 83, 84, 84, 31, 10, 90, 27]
最终方法如下:
def XOR_pack_unpack_strings(s1, s2)
s1_bytes = [s1].pack("H*").unpack("C*")
s2_bytes = [s2].pack("H*").unpack("C*")
s1_bytes.zip(s2_bytes).map { |a, b| a ^ b }.pack('C*')
end
如果速度有问题,请查看fast_xor gem:
require 'xor'
def XOR_fast_xor_strings(s1_hex, s2_hex)
s1 = [s1_hex].pack("H*")
s2 = [s2_hex].pack("H*")
s1.xor!(s2)
end