Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use TextEncoder in IE11?

I'm trying to hash a string. But what is the alternative for function TextEncoder in IE11 and Safari?

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 is a function I got from mozilla

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

like image 504
wubbewubbewubbe Avatar asked Feb 15 '16 21:02

wubbewubbewubbe


People also ask

What is TextEncoder?

TextEncoder is used to convert a given string to utf-8 standard. It retunes an Uint8Array from the string. TextDecoder is used to covert a stream of bytes into a stream of code points. It can decode UTF-8 , ISO-8859-2, KOI8-R, GBK etc. Following is the code for TextDecoder and TextEncoder in JavaScript −

What is TextEncoder in node JS?

TextEncoder.encode() Takes a string as input, and returns a Uint8Array containing UTF-8 encoded text. TextEncoder.encodeInto() Takes a string to encode and a destination Uint8Array to put resulting UTF-8 encoded text into, and returns a dictionary object indicating the progress of the encoding.


1 Answers

Edit: I just ended up using the SHA256 routine from http://www.movable-type.co.uk/scripts/sha256.html because I didn't need high performance, and the code is short and sweet and the same code path is used everywhere. The crypto.subtle API turned out to have too many corner cases where it failed for me (I had problems on some mobile devices, apart from the Chrome issue linked below that caused me grief, and I needed to support older browsers too).

I wrote this function for IE11 which worked for me (although hardly tested):

    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;
    }

Be aware there are other problems because IE11 doesn't have promises, and msCrypto.subtle.digest() is synchronous. The following might work for you, although you should fix the hacks (it needs work to make it robust and to use a Promise polyfill):

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

Also be aware of this Chrome issue which you can use the regexp /^https:|^file:|^http:\/\/localhost|^http:\/\/127.0.0.1/.test(location.protocol) to test for.

like image 171
robocat Avatar answered Sep 22 '22 16:09

robocat