代码之家  ›  专栏  ›  技术社区  ›  zanona oldmanwiggins

将c自定义getsha512函数转换为ruby

  •  0
  • zanona oldmanwiggins  · 技术社区  · 14 年前

    我想知道是否有人能帮我把这个方法转换成Ruby,这有可能吗?

    public static string getSHA512(string str){
        UnicodeEncoding UE = new UnicodeEncoding();
        byte[] HashValue = null;
        byte[] MessageBytes = UE.GetBytes(str);
        System.Security.Cryptography.SHA512Managed SHhash = new System.Security.Cryptography.SHA512Managed();
        string strHex = "";
        HashValue = SHhash.ComputeHash(MessageBytes);
        foreach (byte b in HashValue){
            strHex += string.Format("{0:x2}", b);
        }
        return strHex;
    }
    

    提前谢谢


    更新:

    我只是想澄清一下,不幸的是,它的方法不只是用于sha512代,而是一个自定义的方法。我相信Digest::sha512.hexDigest只是一个shhast实例,但是如果仔细查找该方法,您会发现它与简单的哈希生成稍有不同。 遵循两个函数的结果。

    # in C#
    getSHA512("hello") => "5165d592a6afe59f80d07436e35bd513b3055429916400a16c1adfa499c5a8ce03a370acdd4dc787d04350473bea71ea8345748578fc63ac91f8f95b6c140b93"
    
    # in Ruby
    Digest::SHA512.hexdigest("hello") || Digest::SHA2 => "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043" 
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   Jörg W Mittag    14 年前
    require 'digest/sha2'
    
    class String
      def sha512
        Digest::SHA2.new(512).hexdigest(encode('UTF-16LE'))
      end
    end
    
    'hello'.sha512 # => '5165d592a6afe59f80d07436e35bd…5748578fc63ac91f8f95b6c140b93'
    

    和StackOverflow上的所有代码片段一样,我总是假设Ruby的最新版本。这是一个也适用于Ruby1.8的软件:

    require 'iconv'
    require 'digest/sha2'
    
    class String
      def sha512(src_enc='UTF-8')
        Digest::SHA2.new(512).hexdigest(Iconv.conv(src_enc, 'UTF-16LE', self))
      end
    end
    
    'hello'.sha512 # => '5165d592a6afe59f80d07436e35bd…5748578fc63ac91f8f95b6c140b93'
    

    注意,在这种情况下,你必须 知道 告诉Ruby字符串的显式编码。在Ruby1.9中,Ruby总是知道字符串的编码方式,并会在需要时进行相应的转换。我选择UTF-8作为默认编码,因为它与ASCII向后兼容,是Internet上的标准编码,在其他方面也被广泛使用。但是,例如.NET和Java都使用UTF-16LE,而不是UTF-8。如果字符串不是UTF-8或ASCII编码的,则必须将编码名称传入 sha512 方法。


    主题外:9行代码减为1。我爱红宝石!

    实际上,这有点不公平。你可以这样写:

    var messageBytes = new UnicodeEncoding().GetBytes(str);
    var hashValue = new System.Security.Cryptography.SHA512Managed().
        ComputeHash(messageBytes);
    return hashValue.Aggregate<byte, string>("",
        (s, b) => s += string.Format("{0:x2}", b)
    );
    

    实际上只有3行(stackoverflow的布局可以分成5行),最重要的是摆脱了20世纪50年代那种丑陋的风格 for 循环一个美好的1960年代风格的折叠(又名。 reduce 又名。 inject 又名。 Aggregate 又名。 inject:into: …都一样)。

    也许还有更优雅的方式来写这个,但是a)我不知道c和.net,b)这个问题是关于Ruby的。聚焦,J_¶rg,聚焦!-)

    啊……找到了:

    return string.Join("", from b in hashValue select string.Format("{0:x2}", b));
    

    知道 必须有一个相当于Ruby的 Enumerable#join 我只是找错地方了。

        2
  •  0
  •   Sjoerd    14 年前

    使用 Digest::SHA2 班级。