显然这曾经适用于 ruby 1.8.7 但不幸的是不适用于 1.9.2
class String
def xor(key)
text = dup
text.length.times {|n| text[n] ^= key[n.modulo key.size] }
text
end
end
def encode(_original, _pass = 'testvendor')
_original.xor(_pass)
end
puts encode('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')
#output=>
8
EE
DEBDREBDEVSR
TTTT
TNZV0D
SE E CRVSETENR D
TT
EKS0DSO VD
EVVTE S
RSREXE+E T
RR
T _TOEDE RO E
TTD
K
它返回
NoMethodError: undefined method `^' for "V":String
关于如何让它工作的任何想法?
非常感谢
最佳答案
在 1.8 中,String#[]
方法返回一个 Fixnum,它是指定索引处的字节。在较新的版本中,String#[]
返回一个字符串,因为字符串是由字符组成的,字符到字节的映射取决于编码。看起来您正在使用 String 作为字节缓冲区,因此您应该在 Array 而不是 String 中工作:
class Array
def xor(key)
a = dup
a.length.times { |n| a[n] ^= key[n % key.size] }
a
end
end
然后使用它:
mangled_array = string.codepoints.to_a.xor(key.codepoints.to_a)
然后如果你真的想要一个字符串(它将包含一堆不可打印的控制字符和零字节等等),那么:
mangled_string = mangled_array.inject('') { |s,c| s << c }
然后解压:
mangled_string.
codepoints.
to_a.
xor(key.codepoints.to_a).
inject('') { |s,c| s << c }
所有这些都应该始终保持 UTF-8,这就是您想要的。
如果需要,您可以将 xor
修补到 Enumerable 并跳过 to_a
业务。您也可以将其改编为 String 的补丁。
您不应该再将 String 用于字节缓冲区,您最好使用 Fixnum 数组来进行显式编码处理。
关于ruby - 简单异或 ruby 1.9.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7267548/