2

我有点坚持这一点。我必须与使用加密算法版本的 api 交互,他们似乎从 Ari Kuorikoski 编写的 Typo3 中窃取了该版本。

我需要创建一个 ruby​​ 库来与他们的 api 接口,因此必须将他们的算法移植到 ruby​​ 中,而在加密方面我有点不了解。

这是代码:

private function keyED($txt) { 
$encrypt_key = md5($this->encrypt_key); 
$ctr=0; 
$tmp = ""; 
for ($i=0;$i<strlen($txt);$i++) { 
   if ($ctr==strlen($encrypt_key)) $ctr=0; 
   $tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1); 
   $ctr++; 
} 
return $tmp; 
} 

private function encrypt($txt){ 
srand((double)microtime()*1000000); 
$encrypt_key = md5(rand(0,32000)); 
$ctr=0; 
$tmp = ""; 
for ($i=0;$i<strlen($txt);$i++){ 
   if ($ctr==strlen($encrypt_key)) $ctr=0; 
   $tmp.= substr($encrypt_key,$ctr,1) . 
       (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1)); 
   $ctr++; 
} 
return base64_encode($this->keyED($tmp)); 
}

让我难过的部分是这个,我必须为 ruby​​ 1.8.6 编写它,因为那是它所在的服务器。字符串没有异或。不是说如果有的话我会理解的。

任何帮助、指示、想法将不胜感激。

附录:

我意识到,我没有放任何代码,唯一的困难实际上是 xor 问题,但这是我到目前为止的代码:

def xor(s1,s2)
        if s2.empty? then
            return s1
        else
            a1 = s1.unpack("c*")
            a2 = s2.unpack("c*")
            a2 *= 2 while a2.length < a1.length
            return a1.zip(a2).collect {|c1,c2| c1 ^ c2}.pack("c*")
        end
    end
    def keyED(str)
        encrypt_key = Digest::MD5.digest(@key)
        ctr = 0
        tmp = ''
        for i in 0...str.length do
             ctr = 0 if ctr == encrypt_key.length
             tmp << xor(str.slice(i,1), encrypt_key.slice(ctr,1)).to_s
            ctr = ctr + 1
        end
        return tmp
    end

    # === Ported Code
    # This code was ported from Ari's Typo 3 Session Encryption
    def encrypt(str)
        encrypt_key = Digest::MD5.digest(rand(32000).to_s)
        ctr = 0
        tmp = ''
        for i in 0...str.length do
            ctr=0 if ctr==encrypt_key.length 
            tmp << encrypt_key.slice(ctr,1) << xor(str.slice(i,1), encrypt_key.slice(ctr,1))
            ctr = ctr + 1
        end
        return Base64.encode64(keyED(tmp))
    end
    def decrypt(str)
        txt = keyED(str)
        tmp = ''
        for i in 0...txt.length do 
            md = txt.slice(i,1)
            i = i + 1
            tmp << xor(txt.slice(i,1),md)
        end
        puts "Decrypte string:#{Base64.decode64(tmp)}EOSTRING"
    end
4

2 回答 2

2

埃里克文斯特拉

class String
  def xor(other)
    if other.empty?
      self
    else
      a1        = self.unpack("c*")
      a2        = other.unpack("c*")
      a2 *= 2   while a2.length < a1.length
      a1.zip(a2).collect{|c1,c2| c1^c2}.pack("c*")
    end
  end
end

然后你的代码变成

tmp << str.slice(i,1).xor(encrypt_key.slice(i,1))

根据jolierougeDavid GaramondString#xor的建议,另一种实现:

class String
  def xor(other)
    raise ArgumentError, "Can't bitwise-XOR a String with a non-String" unless other.kind_of? String
    raise ArgumentError, "Can't bitwise-XOR strings of different length" unless self.length == other.length
    (0..self.length-1).collect { |i| self[i] ^ other[i] }.pack("C*")
  end
end
于 2010-01-13T15:54:10.630 回答
0

编者注:最终的工作代码已从问题移至其自己的答案。

最终工作源,基于詹姆斯有用的答案,主要道具!还有大卫·加拉蒙。

def xor(s1,s2)
    raise ArgumentError, "Can't bitwise-XOR a String with a non-String" unless s2.kind_of? String
    raise ArgumentError, "Can't bitwise-XOR strings of different length" unless s1.length == s2.length
    (0..s1.length-1).collect { |i| s1[i] ^ s2[i] }.pack("C*")
end

def keyED(txt,key)
    ctr,tmp = 0,''
    key = Digest::MD5.hexdigest(key)
    for i in 0...txt.length do
        ctr = 0 if ctr == key.length
        str = xor(txt.slice(i,1),key.slice(ctr,1))
        tmp << str
        ctr = ctr + 1
    end

    return tmp
end
def encrypt(txt,key)
    ctr,tmp = 0,''
    ekey = Digest::MD5.hexdigest(rand(32000).to_s)
    for i in 0...txt.length do
        ctr = 0 if ctr == ekey.length
        str = xor(txt.slice(i,1), ekey.slice(ctr,1))
        tmp << ekey.slice(ctr,1) << str
        ctr = ctr + 1
    end
    return Base64.encode64(keyED(tmp,key))
end
于 2015-07-27T21:40:24.200 回答