Hashing password authentication with JavaScript? - javascript

Password = base64 encoded(sha1(nonce+created+secret))
where:
nonce = 186269,
created = 2015-07-08T11:31:53+01:00,
secret = Ok4IWYLBHbKn8juM1gFPvQxadieZmS2
should give ZDg3MTZiZTgwYTMwYWY4Nzc4OGFjMmZhYjA5YzM3MTdlYmQ1M2ZkMw== as password. I am approaching with:
I need the JavaScript for this.

As per security standards this is still not good to perform such coding, one should always do this in backend programming language & get value from API Calls.
but you can use the sha1 function below to do sha1 hashing in JavaScript:
function sha1 (str) {
// discuss at: https://locutus.io/php/sha1/
// original by: Webtoolkit.info (https://www.webtoolkit.info/)
// improved by: Michael White (https://getsprink.com)
// improved by: Kevin van Zonneveld (https://kvz.io)
// input by: Brett Zamir (https://brett-zamir.me)
// note 1: Keep in mind that in accordance with PHP, the whole string is buffered and then
// note 1: hashed. If available, we'd recommend using Node's native crypto modules directly
// note 1: in a steaming fashion for faster and more efficient hashing
// example 1: sha1('Kevin van Zonneveld')
// returns 1: '54916d2e62f65b3afa6e192e6a601cdbe5cb5897'
let hash
try {
const crypto = require('crypto')
const sha1sum = crypto.createHash('sha1')
sha1sum.update(str)
hash = sha1sum.digest('hex')
} catch (e) {
hash = undefined
}
if (hash !== undefined) {
return hash
}
const _rotLeft = function (n, s) {
const t4 = (n << s) | (n >>> (32 - s))
return t4
}
const _cvtHex = function (val) {
let str = ''
let i
let v
for (i = 7; i >= 0; i--) {
v = (val >>> (i * 4)) & 0x0f
str += v.toString(16)
}
return str
}
let blockstart
let i, j
const W = new Array(80)
let H0 = 0x67452301
let H1 = 0xEFCDAB89
let H2 = 0x98BADCFE
let H3 = 0x10325476
let H4 = 0xC3D2E1F0
let A, B, C, D, E
let temp
// utf8_encode
str = unescape(encodeURIComponent(str))
const strLen = str.length
const wordArray = []
for (i = 0; i < strLen - 3; i += 4) {
j = str.charCodeAt(i) << 24 |
str.charCodeAt(i + 1) << 16 |
str.charCodeAt(i + 2) << 8 |
str.charCodeAt(i + 3)
wordArray.push(j)
}
switch (strLen % 4) {
case 0:
i = 0x080000000
break
case 1:
i = str.charCodeAt(strLen - 1) << 24 | 0x0800000
break
case 2:
i = str.charCodeAt(strLen - 2) << 24 | str.charCodeAt(strLen - 1) << 16 | 0x08000
break
case 3:
i = str.charCodeAt(strLen - 3) << 24 |
str.charCodeAt(strLen - 2) << 16 |
str.charCodeAt(strLen - 1) <<
8 | 0x80
break
}
wordArray.push(i)
while ((wordArray.length % 16) !== 14) {
wordArray.push(0)
}
wordArray.push(strLen >>> 29)
wordArray.push((strLen << 3) & 0x0ffffffff)
for (blockstart = 0; blockstart < wordArray.length; blockstart += 16) {
for (i = 0; i < 16; i++) {
W[i] = wordArray[blockstart + i]
}
for (i = 16; i <= 79; i++) {
W[i] = _rotLeft(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1)
}
A = H0
B = H1
C = H2
D = H3
E = H4
for (i = 0; i <= 19; i++) {
temp = (_rotLeft(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff
E = D
D = C
C = _rotLeft(B, 30)
B = A
A = temp
}
for (i = 20; i <= 39; i++) {
temp = (_rotLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff
E = D
D = C
C = _rotLeft(B, 30)
B = A
A = temp
}
for (i = 40; i <= 59; i++) {
temp = (_rotLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff
E = D
D = C
C = _rotLeft(B, 30)
B = A
A = temp
}
for (i = 60; i <= 79; i++) {
temp = (_rotLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff
E = D
D = C
C = _rotLeft(B, 30)
B = A
A = temp
}
H0 = (H0 + A) & 0x0ffffffff
H1 = (H1 + B) & 0x0ffffffff
H2 = (H2 + C) & 0x0ffffffff
H3 = (H3 + D) & 0x0ffffffff
H4 = (H4 + E) & 0x0ffffffff
}
temp = _cvtHex(H0) + _cvtHex(H1) + _cvtHex(H2) + _cvtHex(H3) + _cvtHex(H4)
return temp.toLowerCase()
}
// create sha1
var e = sha1('186269'+'2015-07-08T11:31:53+01:00'+'Ok4IWYLBHbKn8juM1gFPvQxadieZmS2');
console.log(e)
// to base64 encoding
var encoded = btoa(e)
console.log(encoded)
Function link: https://locutus.io/php/sha1/

Related

Unknow json response from Sencha based api

I am having trouble decoding the following json response from a sencha based api.
I tried decoding it to base64 string but the end result was always malformed and has many unrecognized characters.
function handleServerReponse(a) {
if (a.substr(0, 5) == 'I:Qc[') {
var f = 5;
var e = (a.substr(5) + '').split('');
var d = [];
for (var b = e.length - 1; b >= 0; b--) {
d[b] = String.fromCharCode(e[b].charCodeAt(0) - f)
}
var c = d.join('');
//c = fix_utf8(base64_decode(c));
//c = base64_decode(c);
a = c
}
return a
}
function fix_utf8(c) {
var d = []
, a = 0
, b = 0
, e = 0
, f = 0;
while (a < c.length) {
b = c.charCodeAt(a);
if (b < 128) {
d.push(String.fromCharCode(b));
a++
} else {
if (b > 191 && b < 224) {
e = c.charCodeAt(a + 1);
d.push(String.fromCharCode((b & 31) << 6 | e & 63));
a += 2
} else {
e = c.charCodeAt(a + 1);
f = c.charCodeAt(a + 2);
d.push(String.fromCharCode((b & 15) << 12 | (e & 63) << 6 | f & 63));
a += 3
}
}
}
return d.join('')
}
function base64_decode(a) {
var e = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var f, j, n, l, m, h, i, d, b = 0, g = 0, k = '', c = [];
if (!a) {
return a
}
a += '';
do {
l = e.indexOf(a.charAt(b++));
m = e.indexOf(a.charAt(b++));
h = e.indexOf(a.charAt(b++));
i = e.indexOf(a.charAt(b++));
d = l << 18 | m << 12 | h << 6 | i;
f = d >> 16 & 255;
j = d >> 8 & 255;
n = d & 255;
if (h == 64) {
c[g++] = String.fromCharCode(f)
} else {
if (i == 64) {
c[g++] = String.fromCharCode(f, j)
} else {
c[g++] = String.fromCharCode(f, j, n)
}
}
} while (b < a.length);k = c.join('');
return k
}
function utf8_from_str(s) {
for(var i=0, enc = encodeURIComponent(s), a = []; i < enc.length;) {
if(enc[i] === '%') {
a.push(parseInt(enc.substr(i+1, 2), 16))
i += 3
} else {
a.push(enc.charCodeAt(i++))
}
}
return a
}
function utf8_to_str(a) {
for(var i=0, s=''; i<a.length; i++) {
var h = a[i].toString(16)
if(h.length < 2) h = '0' + h
s += '%' + h
}
return decodeURIComponent(s)
}
The js function above just tries to convert into utf-8 but there are still non-recognised characters in the resulting json.
The API response I'm trying to decode is
I:Qc[j~O~_]S6gMWNougj~OVhr>|_]O5jZyqjXN;NoZ}SYl~TYN}SnNxNp}{griuiM[p_XN;Nn5}RYhzRoZ9RV~Nn|nYLK5f]W6_LZnTnNRn99RY^~TYJnQHOYiLK5_XN;NpSGNn|nWpqVZ~N;No^|SRnQHOIf]W:NotnYJJlXp>RYJJnQHOff]GLf]_qNotnTYN|RhnQHOG_LW~_]SNotnSYZ7RHGIVZ:JYJ[RXZiN[HGJZnNxNqOm_LK~XZVnTnOVRYqHRYF8WXNxNqGZj]GqNotnZ5_XNn|n[]SqV7>p_[WuiL}qNotnZ7qz_7}qNJ_mg\qxjXGX_]Su_L[z^7ZnQHOH_\WNotnR~NxNpOmiLmNotnRnNxNqS}WsVnTnN~QIV6R~NxNp}{iKSujrZnTnN}SX|8RIFnQHORg8WYf]uqV\S~_]RnTnN|QoVnQHO__\K~Vs[ugMVnTnN}TY^7Nn|nf]SY^\6qY\KugLqz_5>~W]mqg]G5NotnYr=nQHOG[p5nTnNpRn|6SoFxSIF|Nn|nV]_mf\}m^r}qW]K6f]W:NotnOIVTH||RoVnQHOugp_{hr[ogL>i]OqNotnYr=nQHOR^]S5[MOmgsSr_]OX_\SJ^]WqY\>ziLm__\K~NotnV][sNIN|RYNnQHOR^]S5[MOmgsSr_]O\^\}6_XN;NnV}QIh8RH|6RIFnQHOuh5}uh8Wq_J_{hqSmgLZnTnOTg~NxNp}uh8WNou<Nrm~_\^nTnN{ioJ{hMO{hL[~iLqqh~>VRYqHRYF8WX>xf]S5h~O>QHOIg7:5^\S5h~N;j~Othr[rNotnQ8^}Q8G~g8GqhsWu_]R{ZIJ:VoJ|S5Z{hL[~h7>zh~>rf\[x_MR{Y8_qhs_u_]hnkX|nZLm{iL>[rqp_\>Nou<Nrm~_\^nTnN{ioJ{hMO{hL[~iLqqh~>VRYqHRYF8WX>|fL>5g8S7f\Wqg8RnkX|n[]GshrKp_Z}ugryLg8Oq^7}{h8[~_]RnTsxn_s[z^8Wug79nTnOofLKz_7[Yi\O^8OuhMWug79nQHOxf\:wiL[9iHN;NqGx_\K_XG[hLi~^\WqNs5xNq[|_8Om_L[Rf\:w[MOmgsSm^8Wug7:Nou<Nr_6grS5f\>zNotn^7mmgriqZ8[nh7S~f]G5f\>zNn|ngLqzf8WqjMVnTnOVgL[mh7Zl[]GshrKp_XO>QHO[hLi~^\WqYLqzf5qzir[iL6qgsWGgrKxj]Suh~N;j~Ori\:oiLq{gnN;NrSt^\:s_[S6^sSohrq|iLq{gnNxNr}ugry5_]m5NotnZL}q^]SqNK[|_8Om_LZnkX|n[]GshrKp_Z}ugryIg76|^]Om^r}qh~N;j~Ori\:oiLq{gnN;NrSt^\:s_[S6^sSohrq|iLq{gnNxNr}ugry5_]m5NotnZL}q^]SqNK[|_8Om_LZnk]6ikVBB

Decode encripted/base64 string

I am working on a project where I need to decode the following string:
I:Qc[j~O~_]S6gMWNougj~OVhr>|_]O5jZyqjXN;NoZ}SYl~TYN}SnNxNp}{griuiM[p_XN;Nn5}RYhzRoZ9RV~Nn|nYLK5f]W6_LZnTnNRn99RY^~TYJnQHOYiLK5_XN;NpSGNn|nWpqVZ~N;No^|SRnQHOIf]W:NotnYJJlXp>RYJJnQHOff]GLf]_qNotnTYN|RhnQHOG_LW~_]SNotnSYZ7RHGIVZ:JYJ[RXZiN[HGJZnNxNqOm_LK~XZVnTnOVRYqHRYF8WXNxNqGZj]GqNotnZ5_XNn|n[]SqV7>p_[WuiL}qNotnZ7qz_7}qNJ_mg\qxjXGX_]Su_L[z^7ZnQHOH_\WNotnR~NxNpOmiLmNotnRnNxNqS}WsVnTnN~QIV6R~NxNp}{iKSujrZnTnN}SX|8RIFnQHORg8WYf]uqV\S~_]RnTnN|QoVnQHO__\K~Vs[ugMVnTnN}TY^7Nn|nf]SY^\6qY\KugLqz_5>~W]mqg]G5NotnYr=nQHOG[p5nTnNpRn|6SoFxSIF|Nn|nV]_mf\}m^r}qW]K6f]W:NotnOIVTH||RoVnQHOugp_{hr[ogL>i]OqNotnYr=nQHOR^]S5[MOmgsSr_]OX_\SJ^]WqY\>ziLm__\K~NotnV][sNIN|RYNnQHOR^]S5[MOmgsSr_]O\^\}6_XN;NnV}QIh8RH|6RIFnQHOuh5}uh8Wq_J_{hqSmgLZnTnOTg~NxNp}uh8WNou<Nrm~_\^nTnN{ioJ{hMO{hL[~iLqqh~>VRYqHRYF8WX>xf]S5h~O>QHOIg7:5^\S5h~N;j~Othr[rNotnQ8^}Q8G~g8GqhsWu_]R{ZIJ:VoJ|S5Z{hL[~h7>zh~>rf\[x_MR{Y8_qhs_u_]hnkX|nZLm{iL>[rqp_\>Nou<Nrm~_\^nTnN{ioJ{hMO{hL[~iLqqh~>VRYqHRYF8WX>|fL>5g8S7f\Wqg8RnkX|n[]GshrKp_Z}ugryLg8Oq^7}{h8[~_]RnTsxn_s[z^8Wug79nTnOofLKz_7[Yi\O^8OuhMWug79nQHOxf\:wiL[9iHN;NqGx_\K_XG[hLi~^\WqNs5xNq[|_8Om_L[Rf\:w[MOmgsSm^8Wug7:Nou<Nr_6grS5f\>zNotn^7mmgriqZ8[nh7S~f]G5f\>zNn|ngLqzf8WqjMVnTnOVgL[mh7Zl[]GshrKp_XO>QHO[hLi~^\WqYLqzf5qzir[iL6qgsWGgrKxj]Suh~N;j~Ori\:oiLq{gnN;NrSt^\:s_[S6^sSohrq|iLq{gnNxNr}ugry5_]m5NotnZL}q^]SqNK[|_8Om_LZnkX|n[]GshrKp_Z}ugryIg76|^]Om^r}qh~N;j~Ori\:oiLq{gnN;NrSt^\:s_[S6^sSohrq|iLq{gnNxNr}ugry5_]m5NotnZL}q^]SqNK[|_8Om_LZnk]6ikVBB
I believe I was able to extract the following JavaScript functions that are needed to decode the string:
function handleServerReponse(a) {
if (a.substr(0, 5) == 'I:Qc[') {
var f = 5;
var e = (a.substr(5) + '').split('');
var d = [];
for (var b = e.length - 1; b >= 0; b--) {
d[b] = String.fromCharCode(e[b].charCodeAt(0) - f)
}
a = d.join('');
}
return a
}
function fix_utf8(c) {
var d = []
, a = 0
, b = 0
, e = 0
, f = 0;
while (a < c.length) {
b = c.charCodeAt(a);
if (b < 128) {
d.push(String.fromCharCode(b));
a++
} else {
if (b > 191 && b < 224) {
e = c.charCodeAt(a + 1);
d.push(String.fromCharCode((b & 31) << 6 | e & 63));
a += 2
} else {
e = c.charCodeAt(a + 1);
f = c.charCodeAt(a + 2);
d.push(String.fromCharCode((b & 15) << 12 | (e & 63) << 6 | f & 63));
a += 3
}
}
}
return d.join('')
}
function base64_decode(a) {
var e = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var f, j, n, l, m, h, i, d, b = 0, g = 0, k = '', c = [];
if (!a) {
return a
}
a += '';
do {
l = e.indexOf(a.charAt(b++));
m = e.indexOf(a.charAt(b++));
h = e.indexOf(a.charAt(b++));
i = e.indexOf(a.charAt(b++));
d = l << 18 | m << 12 | h << 6 | i;
f = d >> 16 & 255;
j = d >> 8 & 255;
n = d & 255;
if (h == 64) {
c[g++] = String.fromCharCode(f)
} else {
if (i == 64) {
c[g++] = String.fromCharCode(f, j)
} else {
c[g++] = String.fromCharCode(f, j, n)
}
}
} while (b < a.length);k = c.join('');
return k
}
function utf8_from_str(s) {
for(var i=0, enc = encodeURIComponent(s), a = []; i < enc.length;) {
if(enc[i] === '%') {
a.push(parseInt(enc.substr(i+1, 2), 16))
i += 3
} else {
a.push(enc.charCodeAt(i++))
}
}
return a
}
function utf8_to_str(a) {
for(var i=0, s=''; i<a.length; i++) {
var h = a[i].toString(16)
if(h.length < 2) h = '0' + h
s += '%' + h
}
return decodeURIComponent(s)
}
After different attemps/combinations this is how I am using the code:
var c = handleServerReponse('encoded string above');
c = base64_decode(c);
c = utf8_from_str(c);
c = utf8_to_str(c);
c = fix_utf8(c);
And this is the result I am getting. As you can notice, it seems to be a JSON string but is not decoded properly. Any hints on how I can decode it properly?
{"resultHȔ뜙\힒ٞHLMNM苈㛛隝YHLLMˌ펌C""¤ƗF燖FR#⠈蠄؈䄈ɍхє訉
谉%AL計؀Ӣ,"City":"LA JOLLA","ZipFive":"9201ȋٙ霒#⣓Sc4䄄TĔt傄E""¥&F$䂣⥃䣓tR"¥G熒#⥴e""¥W6T6憕F熆R#⥶榶ƒf層ቕͥᕹ픈ɉ䈎茈눐蝚#⣢"¥7gB#⣢ÃS2"¤ƷE6禒#⣓Ró"¤ƷE6禔
ɕ̈舀萈ɥᲂuilt":"1966","isS﹓憖洷$W斗B#⤦⢂$dң⢃"ÓcÃ"¤fᅉᕕŕ呤計и,024","inForeclo]\鈎蓛ȋ㘜ݕ蛜ٙ\䙴FFT�ᥑr":"Aug 2012","LastTransferXǖR#⢃ósÓ"¦紆緆VDf祶ƒ#⤦⢂$Ɨ7D詬顉梺"/v1/properties/P19B107E/lists"},"Cont`ݜȎ陈݌Kܜ뜙\횙\˔NP쌍ыܙ\웛싙ꖆG2䷦W'f旲'҂%淆噥ៈꜙb#⢷c燦熗'F旲僓䣓tR熆熷7fᕽ̉䰉U]Ʌᕱ幭퉕�͕ɕ̈鬉镹푥�艍ᅹ핍Ҙܚ\[ۈ눛淆W炣⥆ƅe UpgraH圙ܘYS浇&綖7F涤詬陕鍑ﮢ:"changeSubscriptkۈ눛[ꝙ^X\و\ܘYH圙ܘFTƖ洖禕ѵ幑酱卥̈鬉鞣tion":"chc陔ݘ옜ꜝ[ۈ눛[ꝙ^X\و\ܘYH圙ܘYS[ꐛۜ\蘛\Ȏ�F涢#⦶湝单鍍ɥQ彸谉᥹푕ᐈ艁ᕅ͔ᕁ퉅ᔉ嵵䀀

Shorter version of md5 using JavaScript..?

I have an array of objects in a JSON file. The objects don't have unique ids so I need to create either a unique id, or a unique string.
[
{
"name": "Jack Potts",
"age": "56"
}, {
"name": "Rusty Carr",
"age": "31"
}
]
I know I can use MD5, passing in the object, but I'm going to use the string in a URL, so I'd prefer it to be shorter.
Rather than /people/3449c9e5e332f1dbb81505cd739fbf3f, I'd prefer something more like /people/1dbb81505.
It still needs to be a representation of the object because I'm going to lookup the person again from the URL.
Is there anything that produces a string shorter than the MD5 string..?
I'm going to guess that MD5 is my best/only option, but I thought I'd ask.
UPDATE
I maybe wasn't as clear as I could have been. I don't just need to generate a unique id. I won't be updating the JSON file with whatever I generate.
I need a way to take the object in question, create a URL for it, then when the URL is visited use the URL to get back to that object in the array.
As far as I know, if you pass in the same string to MD5 over and over, it will always return the same MD5 string because it's a representation. Don't people use this when storing passwords in a database for the same reason?
Maybe MD5 is fine, I just thought there might be something which produced a shorter string which is a representation of the data. That's my question.
UPDATE 2
The people in the array may change. People may be added and removed so using the array index won't work.
If you just want a shorter output that MD5 but are otherwise satisfied with the uniqueness just truncate to the length you need, each bit is as random as any other bit, that is any subset of the bits you choose are just as good as any other subset.
But realize that if two names are the same you will get the same hash.
As you must realize the shorter the hash the higher change of a collision, you are making a tradeoff of hash length vs uniqueness, that is not bad, just be sure you have enough uniqueness for your needs.
Use the following function:
function generateUID() {
var firstPart = (Math.random() * 46656) | 0;
var secondPart = (Math.random() * 46656) | 0;
firstPart = ("000" + firstPart.toString(36)).slice(-3);
secondPart = ("000" + secondPart.toString(36)).slice(-3);
return firstPart + secondPart;
}
A 6-character alphanumeric sequence is good enough to randomly index a 10k collection (366 = 2.2 billion and 363 = 46656).
I won't be updating the JSON file with whatever I generate.
I need a way to take the object in question, create a URL for it, then when the URL is visited use the URL to get back to that object in the array.
Then use the index of the object in the array: that way people/0 will return {"name": "Jack Potts", "age": "56"}, people/1 will return {"name": "Rusty Carr", "age": "31"}, and so on...
I suggest you use sha1, it proces a relatively short hash. Supposing your data set is relatively limited < 1000000000000...etc... items chances of collisions should be minimal.
https://github.com/emn178/js-sha1 is a nice library
edit modified this to make it shorter
It now does a substring, + a collision detection modification that should be dependable, as long as the order of the items doesn't change if they have the smae values. But then again, if they have the same values it shouldn't matter ;-)
/*
* [js-sha1]{#link https://github.com/emn178/js-sha1}
*
* #version 0.4.1
* #author Chen, Yi-Cyuan [emn178#gmail.com]
* #copyright Chen, Yi-Cyuan 2014-2016
* #license MIT
*/
/*jslint bitwise: true */
(function() {
'use strict';
var root = typeof window === 'object' ? window : {};
var NODE_JS = !root.JS_SHA1_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = global;
}
var COMMON_JS = !root.JS_SHA1_NO_COMMON_JS && typeof module === 'object' && module.exports;
var AMD = typeof define === 'function' && define.amd;
var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [-2147483648, 8388608, 32768, 128];
var SHIFT = [24, 16, 8, 0];
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
var blocks = [];
var createOutputMethod = function (outputType) {
return function (message) {
return new Sha1(true).update(message)[outputType]();
};
};
var createMethod = function () {
var method = createOutputMethod('hex');
if (NODE_JS) {
method = nodeWrap(method);
}
method.create = function () {
return new Sha1();
};
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(type);
}
return method;
};
var nodeWrap = function (method) {
var crypto = require('crypto');
var Buffer = require('buffer').Buffer;
var nodeMethod = function (message) {
if (typeof message === 'string') {
return crypto.createHash('sha1').update(message, 'utf8').digest('hex');
} else if (message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
} else if (message.length === undefined) {
return method(message);
}
return crypto.createHash('sha1').update(new Buffer(message)).digest('hex');
};
return nodeMethod;
};
function Sha1(sharedMemory) {
if (sharedMemory) {
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
this.blocks = blocks;
} else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
this.h0 = 0x67452301;
this.h1 = 0xEFCDAB89;
this.h2 = 0x98BADCFE;
this.h3 = 0x10325476;
this.h4 = 0xC3D2E1F0;
this.block = this.start = this.bytes = 0;
this.finalized = this.hashed = false;
this.first = true;
}
Sha1.prototype.update = function (message) {
if (this.finalized) {
return;
}
var notString = typeof(message) !== 'string';
if (notString && message.constructor === root.ArrayBuffer) {
message = new Uint8Array(message);
}
var code, index = 0, i, length = message.length || 0, blocks = this.blocks;
while (index < length) {
if (this.hashed) {
this.hashed = false;
blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
if(notString) {
for (i = this.start; index < length && i < 64; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
} else {
for (i = this.start; index < length && i < 64; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
}
this.lastByteIndex = i;
this.bytes += i - this.start;
if (i >= 64) {
this.block = blocks[16];
this.start = i - 64;
this.hash();
this.hashed = true;
} else {
this.start = i;
}
}
return this;
};
Sha1.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex;
blocks[16] = this.block;
blocks[i >> 2] |= EXTRA[i & 3];
this.block = blocks[16];
if (i >= 56) {
if (!this.hashed) {
this.hash();
}
blocks[0] = this.block;
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
}
blocks[15] = this.bytes << 3;
this.hash();
};
Sha1.prototype.hash = function () {
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4;
var f, j, t, blocks = this.blocks;
for(j = 16; j < 80; ++j) {
t = blocks[j - 3] ^ blocks[j - 8] ^ blocks[j - 14] ^ blocks[j - 16];
blocks[j] = (t << 1) | (t >>> 31);
}
for(j = 0; j < 20; j += 5) {
f = (b & c) | ((~b) & d);
t = (a << 5) | (a >>> 27);
e = t + f + e + 1518500249 + blocks[j] << 0;
b = (b << 30) | (b >>> 2);
f = (a & b) | ((~a) & c);
t = (e << 5) | (e >>> 27);
d = t + f + d + 1518500249 + blocks[j + 1] << 0;
a = (a << 30) | (a >>> 2);
f = (e & a) | ((~e) & b);
t = (d << 5) | (d >>> 27);
c = t + f + c + 1518500249 + blocks[j + 2] << 0;
e = (e << 30) | (e >>> 2);
f = (d & e) | ((~d) & a);
t = (c << 5) | (c >>> 27);
b = t + f + b + 1518500249 + blocks[j + 3] << 0;
d = (d << 30) | (d >>> 2);
f = (c & d) | ((~c) & e);
t = (b << 5) | (b >>> 27);
a = t + f + a + 1518500249 + blocks[j + 4] << 0;
c = (c << 30) | (c >>> 2);
}
for(; j < 40; j += 5) {
f = b ^ c ^ d;
t = (a << 5) | (a >>> 27);
e = t + f + e + 1859775393 + blocks[j] << 0;
b = (b << 30) | (b >>> 2);
f = a ^ b ^ c;
t = (e << 5) | (e >>> 27);
d = t + f + d + 1859775393 + blocks[j + 1] << 0;
a = (a << 30) | (a >>> 2);
f = e ^ a ^ b;
t = (d << 5) | (d >>> 27);
c = t + f + c + 1859775393 + blocks[j + 2] << 0;
e = (e << 30) | (e >>> 2);
f = d ^ e ^ a;
t = (c << 5) | (c >>> 27);
b = t + f + b + 1859775393 + blocks[j + 3] << 0;
d = (d << 30) | (d >>> 2);
f = c ^ d ^ e;
t = (b << 5) | (b >>> 27);
a = t + f + a + 1859775393 + blocks[j + 4] << 0;
c = (c << 30) | (c >>> 2);
}
for(; j < 60; j += 5) {
f = (b & c) | (b & d) | (c & d);
t = (a << 5) | (a >>> 27);
e = t + f + e - 1894007588 + blocks[j] << 0;
b = (b << 30) | (b >>> 2);
f = (a & b) | (a & c) | (b & c);
t = (e << 5) | (e >>> 27);
d = t + f + d - 1894007588 + blocks[j + 1] << 0;
a = (a << 30) | (a >>> 2);
f = (e & a) | (e & b) | (a & b);
t = (d << 5) | (d >>> 27);
c = t + f + c - 1894007588 + blocks[j + 2] << 0;
e = (e << 30) | (e >>> 2);
f = (d & e) | (d & a) | (e & a);
t = (c << 5) | (c >>> 27);
b = t + f + b - 1894007588 + blocks[j + 3] << 0;
d = (d << 30) | (d >>> 2);
f = (c & d) | (c & e) | (d & e);
t = (b << 5) | (b >>> 27);
a = t + f + a - 1894007588 + blocks[j + 4] << 0;
c = (c << 30) | (c >>> 2);
}
for(; j < 80; j += 5) {
f = b ^ c ^ d;
t = (a << 5) | (a >>> 27);
e = t + f + e - 899497514 + blocks[j] << 0;
b = (b << 30) | (b >>> 2);
f = a ^ b ^ c;
t = (e << 5) | (e >>> 27);
d = t + f + d - 899497514 + blocks[j + 1] << 0;
a = (a << 30) | (a >>> 2);
f = e ^ a ^ b;
t = (d << 5) | (d >>> 27);
c = t + f + c - 899497514 + blocks[j + 2] << 0;
e = (e << 30) | (e >>> 2);
f = d ^ e ^ a;
t = (c << 5) | (c >>> 27);
b = t + f + b - 899497514 + blocks[j + 3] << 0;
d = (d << 30) | (d >>> 2);
f = c ^ d ^ e;
t = (b << 5) | (b >>> 27);
a = t + f + a - 899497514 + blocks[j + 4] << 0;
c = (c << 30) | (c >>> 2);
}
this.h0 = this.h0 + a << 0;
this.h1 = this.h1 + b << 0;
this.h2 = this.h2 + c << 0;
this.h3 = this.h3 + d << 0;
this.h4 = this.h4 + e << 0;
};
Sha1.prototype.hex = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4;
return HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +
HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +
HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +
HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +
HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +
HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +
HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +
HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +
HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +
HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F] +
HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +
HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +
HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
HEX_CHARS[(h4 >> 28) & 0x0F] + HEX_CHARS[(h4 >> 24) & 0x0F] +
HEX_CHARS[(h4 >> 20) & 0x0F] + HEX_CHARS[(h4 >> 16) & 0x0F] +
HEX_CHARS[(h4 >> 12) & 0x0F] + HEX_CHARS[(h4 >> 8) & 0x0F] +
HEX_CHARS[(h4 >> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F];
};
Sha1.prototype.toString = Sha1.prototype.hex;
Sha1.prototype.digest = function () {
this.finalize();
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4;
return [
(h0 >> 24) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 8) & 0xFF, h0 & 0xFF,
(h1 >> 24) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 8) & 0xFF, h1 & 0xFF,
(h2 >> 24) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 8) & 0xFF, h2 & 0xFF,
(h3 >> 24) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 8) & 0xFF, h3 & 0xFF,
(h4 >> 24) & 0xFF, (h4 >> 16) & 0xFF, (h4 >> 8) & 0xFF, h4 & 0xFF
];
};
Sha1.prototype.array = Sha1.prototype.digest;
Sha1.prototype.arrayBuffer = function () {
this.finalize();
var buffer = new ArrayBuffer(20);
var dataView = new DataView(buffer);
dataView.setUint32(0, this.h0);
dataView.setUint32(4, this.h1);
dataView.setUint32(8, this.h2);
dataView.setUint32(12, this.h3);
dataView.setUint32(16, this.h4);
return buffer;
};
var exports = createMethod();
if (COMMON_JS) {
module.exports = exports;
} else {
root.sha1 = exports;
if (AMD) {
define(function () {
return exports;
});
}
}
})();
+function() {
var HASHLENGTH = 5;
document.getElementById('clickme').onclick = function() {
// get all the values as objects
var values = JSON.parse(document.getElementById('sample').value);
for (var c = 0; c < values.length; c++) {
// Hash it and substring it given the hashlength
values[c].hash = sha1(JSON.stringify(values[c])).substring(0,HASHLENGTH);
// If you don't need the collision detection, you can just remove these loops.
// check for collisions
for(var i = 0;i < c; i++) {
// collision detected. add a dependable value to get a new hash.
if(values[i].hash == values[c].hash) {
if(values[c].hasOwnProperty('_change')) {
values[c]._change = sha1(values[c]._change);
}
else {
values[c]._change = sha1(values[c].hash);
}
c--;break; // return to same thing for a rehash
}
}
}
console.log(JSON.stringify(values,null,4));
}
}();
textarea { width:100%;height:200px;}
<button id="clickme"> Parse </button>
<textarea id="sample">
[
{
"name": "Jack Potts",
"age": "56"
}, {
"name": "Rusty Carr",
"age": "31"
},
{
"name": "Rusty Carr",
"age": "31"
},
{
"name": "Rusty Carr",
"age": "31"
},
{
"name": "Rusty Carr",
"age": "31"
},
{
"name": "Rusty Carr",
"age": "31"
},
{
"name": "Rusty Carr",
"age": "31"
}
]
</textarea>
Here is native JavaScript code to get an MD5 hash, shortened to a desired length. Mind you, the shorter the hash, the more likely you get collisions.
var md5 = function(d){var r = M(V(Y(X(d),8*d.length)));return r.toLowerCase()};function M(d){for(var _,m="0123456789ABCDEF",f="",r=0;r<d.length;r++)_=d.charCodeAt(r),f+=m.charAt(_>>>4&15)+m.charAt(15&_);return f}function X(d){for(var _=Array(d.length>>2),m=0;m<_.length;m++)_[m]=0;for(m=0;m<8*d.length;m+=8)_[m>>5]|=(255&d.charCodeAt(m/8))<<m%32;return _}function V(d){for(var _="",m=0;m<32*d.length;m+=8)_+=String.fromCharCode(d[m>>5]>>>m%32&255);return _}function Y(d,_){d[_>>5]|=128<<_%32,d[14+(_+64>>>9<<4)]=_;for(var m=1732584193,f=-271733879,r=-1732584194,i=271733878,n=0;n<d.length;n+=16){var h=m,t=f,g=r,e=i;f=md5_ii(f=md5_ii(f=md5_ii(f=md5_ii(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_ff(f=md5_ff(f=md5_ff(f=md5_ff(f,r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+0],7,-680876936),f,r,d[n+1],12,-389564586),m,f,d[n+2],17,606105819),i,m,d[n+3],22,-1044525330),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+4],7,-176418897),f,r,d[n+5],12,1200080426),m,f,d[n+6],17,-1473231341),i,m,d[n+7],22,-45705983),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+8],7,1770035416),f,r,d[n+9],12,-1958414417),m,f,d[n+10],17,-42063),i,m,d[n+11],22,-1990404162),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+12],7,1804603682),f,r,d[n+13],12,-40341101),m,f,d[n+14],17,-1502002290),i,m,d[n+15],22,1236535329),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+1],5,-165796510),f,r,d[n+6],9,-1069501632),m,f,d[n+11],14,643717713),i,m,d[n+0],20,-373897302),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+5],5,-701558691),f,r,d[n+10],9,38016083),m,f,d[n+15],14,-660478335),i,m,d[n+4],20,-405537848),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+9],5,568446438),f,r,d[n+14],9,-1019803690),m,f,d[n+3],14,-187363961),i,m,d[n+8],20,1163531501),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+13],5,-1444681467),f,r,d[n+2],9,-51403784),m,f,d[n+7],14,1735328473),i,m,d[n+12],20,-1926607734),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+5],4,-378558),f,r,d[n+8],11,-2022574463),m,f,d[n+11],16,1839030562),i,m,d[n+14],23,-35309556),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+1],4,-1530992060),f,r,d[n+4],11,1272893353),m,f,d[n+7],16,-155497632),i,m,d[n+10],23,-1094730640),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+13],4,681279174),f,r,d[n+0],11,-358537222),m,f,d[n+3],16,-722521979),i,m,d[n+6],23,76029189),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+9],4,-640364487),f,r,d[n+12],11,-421815835),m,f,d[n+15],16,530742520),i,m,d[n+2],23,-995338651),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+0],6,-198630844),f,r,d[n+7],10,1126891415),m,f,d[n+14],15,-1416354905),i,m,d[n+5],21,-57434055),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+12],6,1700485571),f,r,d[n+3],10,-1894986606),m,f,d[n+10],15,-1051523),i,m,d[n+1],21,-2054922799),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+8],6,1873313359),f,r,d[n+15],10,-30611744),m,f,d[n+6],15,-1560198380),i,m,d[n+13],21,1309151649),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+4],6,-145523070),f,r,d[n+11],10,-1120210379),m,f,d[n+2],15,718787259),i,m,d[n+9],21,-343485551),m=safe_add(m,h),f=safe_add(f,t),r=safe_add(r,g),i=safe_add(i,e)}return Array(m,f,r,i)}function md5_cmn(d,_,m,f,r,i){return safe_add(bit_rol(safe_add(safe_add(_,d),safe_add(f,i)),r),m)}function md5_ff(d,_,m,f,r,i,n){return md5_cmn(_&m|~_&f,d,_,r,i,n)}function md5_gg(d,_,m,f,r,i,n){return md5_cmn(_&f|m&~f,d,_,r,i,n)}function md5_hh(d,_,m,f,r,i,n){return md5_cmn(_^m^f,d,_,r,i,n)}function md5_ii(d,_,m,f,r,i,n){return md5_cmn(m^(_|~f),d,_,r,i,n)}function safe_add(d,_){var m=(65535&d)+(65535&_);return(d>>16)+(_>>16)+(m>>16)<<16|65535&m}function bit_rol(d,_){return d<<_|d>>>32-_}
function tinymd5(str, length) {
length = length || 16;
str = window.btoa(md5(str)).replace(/[aiueoAIUEO\+\/]/g, '').substring(0, length);
if(str.length < length) {
str += Array(length - str.length).join('=');
}
return str;
}
// example usage:
var shortHash = tinymd5(JSON.stringify(someObj), 16);
The md5 function is from https://stackoverflow.com/a/33486055/7475450
The tinymd5 function is code converted to JavaScript based on https://rolandeckert.com/notes/md5
Maybe it works using 3125 chars :
const md5=str=>{var a=(r,t)=>r+t&0xffffffff,l=(r,t)=>{var e=r[0],n=r[1],o=r[2],l=r[3],e=h(e,n,o,l,t[0],7,-0x28955b88),l=h(l,e,n,o,t[1],12,-0x173848aa),o=h(o,l,e,n,t[2],17,0x242070db),n=h(n,o,l,e,t[3],22,-0x3e423112);e=h(e,n,o,l,t[4],7,-0xa83f051),l=h(l,e,n,o,t[5],12,0x4787c62a),o=h(o,l,e,n,t[6],17,-0x57cfb9ed),n=h(n,o,l,e,t[7],22,-0x2b96aff),e=h(e,n,o,l,t[8],7,0x698098d8),l=h(l,e,n,o,t[9],12,-0x74bb0851),o=h(o,l,e,n,t[10],17,-42063),n=h(n,o,l,e,t[11],22,-0x76a32842),e=h(e,n,o,l,t[12],7,0x6b901122),l=h(l,e,n,o,t[13],12,-0x2678e6d),o=h(o,l,e,n,t[14],17,-0x5986bc72),n=h(n,o,l,e,t[15],22,0x49b40821),e=c(e,n,o,l,t[1],5,-0x9e1da9e),l=c(l,e,n,o,t[6],9,-0x3fbf4cc0),o=c(o,l,e,n,t[11],14,0x265e5a51),n=c(n,o,l,e,t[0],20,-0x16493856),e=c(e,n,o,l,t[5],5,-0x29d0efa3),l=c(l,e,n,o,t[10],9,0x2441453),o=c(o,l,e,n,t[15],14,-0x275e197f),n=c(n,o,l,e,t[4],20,-0x182c0438),e=c(e,n,o,l,t[9],5,0x21e1cde6),l=c(l,e,n,o,t[14],9,-0x3cc8f82a),o=c(o,l,e,n,t[3],14,-0xb2af279),n=c(n,o,l,e,t[8],20,0x455a14ed),e=c(e,n,o,l,t[13],5,-0x561c16fb),l=c(l,e,n,o,t[2],9,-0x3105c08),o=c(o,l,e,n,t[7],14,0x676f02d9),n=c(n,o,l,e,t[12],20,-0x72d5b376),e=d(e,n,o,l,t[5],4,-378558),l=d(l,e,n,o,t[8],11,-0x788e097f),o=d(o,l,e,n,t[11],16,0x6d9d6122),n=d(n,o,l,e,t[14],23,-0x21ac7f4),e=d(e,n,o,l,t[1],4,-0x5b4115bc),l=d(l,e,n,o,t[4],11,0x4bdecfa9),o=d(o,l,e,n,t[7],16,-0x944b4a0),n=d(n,o,l,e,t[10],23,-0x41404390),e=d(e,n,o,l,t[13],4,0x289b7ec6),l=d(l,e,n,o,t[0],11,-0x155ed806),o=d(o,l,e,n,t[3],16,-0x2b10cf7b),n=d(n,o,l,e,t[6],23,0x4881d05),e=d(e,n,o,l,t[9],4,-0x262b2fc7),l=d(l,e,n,o,t[12],11,-0x1924661b),o=d(o,l,e,n,t[15],16,0x1fa27cf8),n=d(n,o,l,e,t[2],23,-0x3b53a99b),e=g(e,n,o,l,t[0],6,-0xbd6ddbc),l=g(l,e,n,o,t[7],10,0x432aff97),o=g(o,l,e,n,t[14],15,-0x546bdc59),n=g(n,o,l,e,t[5],21,-0x36c5fc7),e=g(e,n,o,l,t[12],6,0x655b59c3),l=g(l,e,n,o,t[3],10,-0x70f3336e),o=g(o,l,e,n,t[10],15,-0x100b83),n=g(n,o,l,e,t[1],21,-0x7a7ba22f),e=g(e,n,o,l,t[8],6,0x6fa87e4f),l=g(l,e,n,o,t[15],10,-0x1d31920),o=g(o,l,e,n,t[6],15,-0x5cfebcec),n=g(n,o,l,e,t[13],21,0x4e0811a1),e=g(e,n,o,l,t[4],6,-0x8ac817e),l=g(l,e,n,o,t[11],10,-0x42c50dcb),o=g(o,l,e,n,t[2],15,0x2ad7d2bb),n=g(n,o,l,e,t[9],21,-0x14792c6f),r[0]=a(e,r[0]),r[1]=a(n,r[1]),r[2]=a(o,r[2]),r[3]=a(l,r[3])},f=(r,t,e,n,o,l)=>(t=a(a(t,r),a(n,l)),a(t<<o|t>>>32-o,e));let h=(r,t,e,n,o,l,a)=>f(t&e|~t&n,r,t,o,l,a),c=(r,t,e,n,o,l,a)=>f(t&n|e&~n,r,t,o,l,a),d=(r,t,e,n,o,l,a)=>f(t^e^n,r,t,o,l,a),g=(r,t,e,n,o,l,a)=>f(e^(t|~n),r,t,o,l,a);var n="0123456789abcdef".split("");return(t=>{for(let r=0;r<t.length;r++)t[r]=(r=>{let t="",e=0;for(;e<4;e++)t+=n[r>>8*e+4&15]+n[r>>8*e&15];return t})(t[r]);return t.join("")})((r=>{let t=r.length,e=[0x67452301,-0x10325477,-0x67452302,0x10325476],n;for(n=64;n<=r.length;n+=64)l(e,(r=>{let t=[],e;for(e=0;e<64;e+=4)t[e>>2]=r.charCodeAt(e)+(r.charCodeAt(e+1)<<8)+(r.charCodeAt(e+2)<<16)+(r.charCodeAt(e+3)<<24);return t})(r.substring(n-64,n)));r=r.substring(n-64);let o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(n=0;n<r.length;n++)o[n>>2]|=r.charCodeAt(n)<<(n%4<<3);if(o[n>>2]|=128<<(n%4<<3),55<n)for(l(e,o),n=0;n<16;n++)o[n]=0;return o[14]=8*t,l(e,o),e})("string"==typeof str?str:""+str))};

HEX to Base64 converter for JavaScript

Anyone know of a good snippet of JavaScript code to convert HEX encoded strings to base64 encoded strings?
If you're working in Node or using Browserify, you can use
var base64String = Buffer.from(hexString, 'hex').toString('base64')
or
var hexString = Buffer.from(base64String, 'base64').toString('hex')
The excellent comment by #dandavis is modified by StackOverflow, and has some weird hidden characters.
Here it is as one liner :
btoa("a6b580481008e60df9350de170b7e728".match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a, 16));} ).join(""))
or :
function hexToBase64(hexstring) {
return btoa(hexstring.match(/\w{2}/g).map(function(a) {
return String.fromCharCode(parseInt(a, 16));
}).join(""));
}
hexToBase64("a6b580481008e60df9350de170b7e728");
Both return :
"prWASBAI5g35NQ3hcLfnKA=="
Note that the hex string should have an even length :
hexToBase64("00");
// => "AA=="
hexToBase64("000");
// => "AA=="
if (!window.atob) {
var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var table = tableStr.split("");
window.atob = function (base64) {
if (/(=[^=]+|={3,})$/.test(base64)) throw new Error("String contains an invalid character");
base64 = base64.replace(/=/g, "");
var n = base64.length & 3;
if (n === 1) throw new Error("String contains an invalid character");
for (var i = 0, j = 0, len = base64.length / 4, bin = []; i < len; ++i) {
var a = tableStr.indexOf(base64[j++] || "A"), b = tableStr.indexOf(base64[j++] || "A");
var c = tableStr.indexOf(base64[j++] || "A"), d = tableStr.indexOf(base64[j++] || "A");
if ((a | b | c | d) < 0) throw new Error("String contains an invalid character");
bin[bin.length] = ((a << 2) | (b >> 4)) & 255;
bin[bin.length] = ((b << 4) | (c >> 2)) & 255;
bin[bin.length] = ((c << 6) | d) & 255;
};
return String.fromCharCode.apply(null, bin).substr(0, bin.length + n - 4);
};
window.btoa = function (bin) {
for (var i = 0, j = 0, len = bin.length / 3, base64 = []; i < len; ++i) {
var a = bin.charCodeAt(j++), b = bin.charCodeAt(j++), c = bin.charCodeAt(j++);
if ((a | b | c) > 255) throw new Error("String contains an invalid character");
base64[base64.length] = table[a >> 2] + table[((a << 4) & 63) | (b >> 4)] +
(isNaN(b) ? "=" : table[((b << 2) & 63) | (c >> 6)]) +
(isNaN(b + c) ? "=" : table[c & 63]);
}
return base64.join("");
};
}
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null,
str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" "))
);
}
function base64ToHex(str) {
for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) {
var tmp = bin.charCodeAt(i).toString(16);
if (tmp.length === 1) tmp = "0" + tmp;
hex[hex.length] = tmp;
}
return hex.join(" ");
}
I liked the approach from #eric-duminil nevertheless the solution below - avoiding regex - is ~2x faster.
Browser:
function hexToBase64(hexStr) {
return btoa([...hexStr].reduce((acc, _, i) =>
acc += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : ""
,""));
}
OR
// even a bit faster
function hexToBase64(hexStr) {
let base64 = "";
for(let i = 0; i < hexStr.length; i++) {
base64 += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : ""
}
return btoa(base64);
}
Node:
const base64 = Buffer.from(hexStr, 'hex').toString('base64');
Large strings, no btoa
Solution below is good for large strings - if you want to get bytes from base64 then look HERE
function bytesArrToBase64(arr) {
const abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 alphabet
const bin = n => n.toString(2).padStart(8,0); // convert num to 8-bit binary string
const l = arr.length
let result = '';
for(let i=0; i<=(l-1)/3; i++) {
let c1 = i*3+1>=l; // case when "=" is on end
let c2 = i*3+2>=l; // case when "=" is on end
let chunk = bin(arr[3*i]) + bin(c1? 0:arr[3*i+1]) + bin(c2? 0:arr[3*i+2]);
let r = chunk.match(/.{1,6}/g).map((x,j)=> j==3&&c2 ? '=' :(j==2&&c1 ? '=':abc[+('0b'+x)]));
result += r.join('');
}
return result;
}
function hexToBytes(hexString) {
return hexString.match(/.{1,2}/g).map(x=> +('0x'+x));
}
// ---------
// TEST
// ---------
let hexString = "a6b580481008e60df9350de170b7e728";
let bytes = hexToBytes(hexString);
let base64 = bytesArrToBase64(bytes);
console.log(base64);

Javascript: calculate OpenSubtitles hash - getting wrong result

I am trying to calculate correct OpenSubtitles hash code for files in Javascript, but for big files it doesnt work correctly - so I asume, there is problem with size of file (overflow). OpenSubtitles hash with source codes is described here: http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes
I am testing this code with Dummy RAR File (unpacked) - http://www.opensubtitles.org/addons/avi/dummy.rar, correct result is 61f7751fc2a72bfb but this code gives 61f7751ec2a72bfb - so there is some error. I am not good at Javascript. Also I found others got similar problems: http://forum.opensubtitles.org/viewtopic.php?f=8&t=13243 and maybe this works: https://github.com/ka2er/node-opensubtitles-api/blob/master/lib/opensubtitles.js
Question is, what is needed to change, so I get correct hash? Thanks.
function binl2hex(a)
{
var b = 255;
a[1] += a[0] >> 8;
a[0] = a[0] & b;
a[2] += a[1] >> 8;
a[1] = a[1] & b;
a[3] += a[2] >> 8;
a[2] = a[2] & b;
a[4] += a[3] >> 8;
a[3] = a[3] & b;
a[5] += a[4] >> 8;
a[4] = a[4] & b;
a[6] += a[5] >> 8;
a[5] = a[5] & b;
a[7] += a[6] >> 8;
a[6] = a[6] & b;
a[7] = a[7] & b;
for (var d = "0123456789abcdef", e = "", c = 7; c > -1; c--)
e += d.charAt(a[c] >> 4 & 15) + d.charAt(a[c] & 15);
return e
}
$(document).ready(function()
{
jQuery.event.props.push('dataTransfer');
$('#search_field').bind('drop', function(e)
{
var files = e.dataTransfer.files;
$.each(files, function(index, file)
{
if(files.length > 1)
{
$('#top_msg').attr('class', 'msg warn');
$('#top_msg').html('multiple files are <b>not supported</b> (yet)');
return false;
}
if (!files[index].type.match('video.*') && !files[index].name.match(/\.(mkv)$/i))
{
//|| !files[index].name.match('/mkv/i')
$('#top_msg').attr('class', 'msg warn');
$('#top_msg').html('search works only for <b>video</b> files.');
return false;
}
$('#top_msg').html('<b>File upload and hashing in progress</b>...');
$('#top_msg').attr('class', 'msg indicator');
var b = 65536;
fs = file.size;
var e = Array(8);
for (var a = fs, f = 0; f < 8; f++)
{
e[f] = a & 255;
a = a >> 8
}
a = fs;
var c = file.slice(0, b);
var g = new FileReader;
g.onloadend = function (h)
{
if (h.target.readyState == FileReader.DONE)
{
for (var f = h.target.result, d = 0; d < f.length; d++)
e[(d + 8) % 8] += f.charCodeAt(d);
c = file.slice(a - b);
var g = new FileReader;
g.onloadend = function (c)
{
var b = "languages";
if (c.target.readyState == FileReader.DONE)
{
f = c.target.result;
for (d = 0; d < f.length; d++)
e[(d + 8) % 8] += f.charCodeAt(d);
lang = $("#SubLanguageID").multiselect("getChecked").map(function()
{
return this.value
}).get().join(",");
if (lang == "")
lang = "all";
var url = "http://www.opensubtitles.org/" + $(location).attr('pathname').substr(1,2) + "/search/sublanguageid-" + lang + "/moviehash-" + binl2hex(e);
document.location = url;
}
};
g.readAsBinaryString(c)
}
};
g.readAsBinaryString(c)
});
});
});

Categories

Resources