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
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 −
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With