Generate a Hash from string in Javascript

前端 未结 22 1008
不知归路
不知归路 2020-11-22 03:34

I need to convert strings to some form of hash. Is this possible in JavaScript?

I\'m not utilizing a server-side language so I can\'t do it that way.

22条回答
  •  别那么骄傲
    2020-11-22 04:18

    Thanks to the example by mar10, I found a way to get the same results in C# AND Javascript for an FNV-1a. If unicode chars are present, the upper portion is discarded for the sake of performance. Don't know why it would be helpful to maintain those when hashing, as am only hashing url paths for now.

    C# Version

    private static readonly UInt32 FNV_OFFSET_32 = 0x811c9dc5;   // 2166136261
    private static readonly UInt32 FNV_PRIME_32 = 0x1000193;     // 16777619
    
    // Unsigned 32bit integer FNV-1a
    public static UInt32 HashFnv32u(this string s)
    {
        // byte[] arr = Encoding.UTF8.GetBytes(s);      // 8 bit expanded unicode array
        char[] arr = s.ToCharArray();                   // 16 bit unicode is native .net 
    
        UInt32 hash = FNV_OFFSET_32;
        for (var i = 0; i < s.Length; i++)
        {
            // Strips unicode bits, only the lower 8 bits of the values are used
            hash = hash ^ unchecked((byte)(arr[i] & 0xFF));
            hash = hash * FNV_PRIME_32;
        }
        return hash;
    }
    
    // Signed hash for storing in SQL Server
    public static Int32 HashFnv32s(this string s)
    {
        return unchecked((int)s.HashFnv32u());
    }
    

    JavaScript Version

    var utils = utils || {};
    
    utils.FNV_OFFSET_32 = 0x811c9dc5;
    
    utils.hashFnv32a = function (input) {
        var hval = utils.FNV_OFFSET_32;
    
        // Strips unicode bits, only the lower 8 bits of the values are used
        for (var i = 0; i < input.length; i++) {
            hval = hval ^ (input.charCodeAt(i) & 0xFF);
            hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
        }
    
        return hval >>> 0;
    }
    
    utils.toHex = function (val) {
        return ("0000000" + (val >>> 0).toString(16)).substr(-8);
    }
    

提交回复
热议问题