5

文字列をハッシュしようとしています。しかし、IE11 と Safari の関数 TextEncoder の代わりになるものは何ですか?

var string = "foobar";

window.crypto.subtle.digest(

    { "name": "SHA-256" },

    new TextEncoder("utf-8").encode(string)).then(function (hash)
    {
        console.log(hex(hash)); // 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'
    }
);

var string = "foobar";

var buffer = new TextEncoder("utf-8").encode(string); // Uint8Array (ArrayBuffer)
var string = new TextDecoder("utf-8").decode(buffer); // string

console.log("buffer", buffer);
console.log("string '" + string + "'");

hex は mozilla から取得した関数です

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest

4

1 に答える 1

8

編集: http://www.movable-type.co.uk/scripts/sha256.htmlの SHA256 ルーチンを使用することになりました。これは、高性能が必要ないためであり、コードは短くて甘く、同じコードですパスはどこでも使用されます。crypto.subtle API には、失敗する稀なケースが多すぎることが判明しました (下にリンクされている Chrome の問題を除けば、いくつかのモバイル デバイスで問題が発生し、私は悲しみに暮れ、古いブラウザーもサポートする必要がありました)。

私はIE11用にこの関数を書きました(ほとんどテストされていませんが):

    function textEncode(str) {
        if (window.TextEncoder) {
            return new TextEncoder('utf-8').encode(str);
        }
        var utf8 = unescape(encodeURIComponent(str));
        var result = new Uint8Array(utf8.length);
        for (var i = 0; i < utf8.length; i++) {
            result[i] = utf8.charCodeAt(i);
        }
        return result;
    }

IE11 にはプロミスがなく、msCrypto.subtle.digest()同期的であるため、他にも問題があることに注意してください。ハックを修正する必要がありますが、次の方法でうまくいく可能性があります (堅牢にして Promise ポリフィルを使用するには作業が必要です)。

function sha256(str) {
    function hex(buffer) {
        var hexCodes = [];
        var view = new DataView(buffer);
        for (var i = 0; i < view.byteLength; i += 4) {
            var value = view.getUint32(i);
            var stringValue = value.toString(16);
            var padding = '00000000';
            var paddedValue = (padding + stringValue).slice(-padding.length);
            hexCodes.push(paddedValue);
        }
        return hexCodes.join('');
    }
    var buffer = textEncode(str);
    var res = crypto.subtle.digest('SHA-256', buffer);
    if (res.then) {
        return res.then(function (hash) {
            return hex(hash);
        });
    } else if (res.result) {    // IE11
        return {
            then: function(resolver) {
                resolver(hex(res.result));
            }
        }
    }
}

また、正規表現を使用してテストできるこの Chrome の問題にも注意してください。/^https:|^file:|^http:\/\/localhost|^http:\/\/127.0.0.1/.test(location.protocol)

于 2016-04-01T03:01:06.203 に答える