代码之家  ›  专栏  ›  技术社区  ›  J. Martin

从php到ruby的加密算法(vignere变体)

  •  2
  • J. Martin  · 技术社区  · 15 年前

    我有点受不了。我必须与一个API接口,该API使用的加密算法版本似乎是从AriKuorikoski编写的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)); 
    }
    

    让我头疼的是,我必须为Ruby1.8.6编写它,因为这是它将要使用的服务器。字符串没有XOR。如果有的话,我也不会理解。

    任何帮助、指点、想法都会受到赞赏。

    附录:

    我意识到,我没有添加任何代码,唯一的困难实际上是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
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   Community CDub    7 年前

    Erik Veenstra :

    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))
    

    替代的实现 String#xor ,根据建议 jolierouge David Garamond :

    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
    
        2
  •  0
  •   JasonMArcher    9 年前

    编者按:最后的工作代码从问题转移到了自己的答案。

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

    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