added identicons to circles
parent
586ce58894
commit
021954c86b
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* [hi-base32]{@link https://github.com/emn178/hi-base32}
|
||||
*
|
||||
* @version 0.5.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2015-2018
|
||||
* @license MIT
|
||||
*/
|
||||
/*jslint bitwise: true */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var root = typeof window === 'object' ? window : {};
|
||||
var NODE_JS = !root.HI_BASE32_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
|
||||
if (NODE_JS) {
|
||||
root = global;
|
||||
}
|
||||
var COMMON_JS = !root.HI_BASE32_NO_COMMON_JS && typeof module === 'object' && module.exports;
|
||||
var AMD = typeof define === 'function' && define.amd;
|
||||
var BASE32_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('');
|
||||
var BASE32_DECODE_CHAR = {
|
||||
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8,
|
||||
'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16,
|
||||
'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24,
|
||||
'Z': 25, '2': 26, '3': 27, '4': 28, '5': 29, '6': 30, '7': 31
|
||||
};
|
||||
|
||||
var blocks = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
var throwInvalidUtf8 = function (position, partial) {
|
||||
if (partial.length > 10) {
|
||||
partial = '...' + partial.substr(-10);
|
||||
}
|
||||
var err = new Error('Decoded data is not valid UTF-8.'
|
||||
+ ' Maybe try base32.decode.asBytes()?'
|
||||
+ ' Partial data after reading ' + position + ' bytes: ' + partial + ' <-');
|
||||
err.position = position;
|
||||
throw err;
|
||||
};
|
||||
|
||||
var toUtf8String = function (bytes) {
|
||||
var str = '', length = bytes.length, i = 0, followingChars = 0, b, c;
|
||||
while (i < length) {
|
||||
b = bytes[i++];
|
||||
if (b <= 0x7F) {
|
||||
str += String.fromCharCode(b);
|
||||
continue;
|
||||
} else if (b > 0xBF && b <= 0xDF) {
|
||||
c = b & 0x1F;
|
||||
followingChars = 1;
|
||||
} else if (b <= 0xEF) {
|
||||
c = b & 0x0F;
|
||||
followingChars = 2;
|
||||
} else if (b <= 0xF7) {
|
||||
c = b & 0x07;
|
||||
followingChars = 3;
|
||||
} else {
|
||||
throwInvalidUtf8(i, str);
|
||||
}
|
||||
|
||||
for (var j = 0; j < followingChars; ++j) {
|
||||
b = bytes[i++];
|
||||
if (b < 0x80 || b > 0xBF) {
|
||||
throwInvalidUtf8(i, str);
|
||||
}
|
||||
c <<= 6;
|
||||
c += b & 0x3F;
|
||||
}
|
||||
if (c >= 0xD800 && c <= 0xDFFF) {
|
||||
throwInvalidUtf8(i, str);
|
||||
}
|
||||
if (c > 0x10FFFF) {
|
||||
throwInvalidUtf8(i, str);
|
||||
}
|
||||
|
||||
if (c <= 0xFFFF) {
|
||||
str += String.fromCharCode(c);
|
||||
} else {
|
||||
c -= 0x10000;
|
||||
str += String.fromCharCode((c >> 10) + 0xD800);
|
||||
str += String.fromCharCode((c & 0x3FF) + 0xDC00);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
var decodeAsBytes = function (base32Str) {
|
||||
if (!/^[A-Z2-7=]+$/.test(base32Str)) {
|
||||
throw new Error('Invalid base32 characters');
|
||||
}
|
||||
base32Str = base32Str.replace(/=/g, '');
|
||||
var v1, v2, v3, v4, v5, v6, v7, v8, bytes = [], index = 0, length = base32Str.length;
|
||||
|
||||
// 4 char to 3 bytes
|
||||
for (var i = 0, count = length >> 3 << 3; i < count;) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v8 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
|
||||
bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
|
||||
bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
|
||||
bytes[index++] = (v5 << 7 | v6 << 2 | v7 >>> 3) & 255;
|
||||
bytes[index++] = (v7 << 5 | v8) & 255;
|
||||
}
|
||||
|
||||
// remain bytes
|
||||
var remain = length - count;
|
||||
if (remain === 2) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
|
||||
} else if (remain === 4) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
|
||||
bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
|
||||
} else if (remain === 5) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
|
||||
bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
|
||||
bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
|
||||
} else if (remain === 7) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
bytes[index++] = (v1 << 3 | v2 >>> 2) & 255;
|
||||
bytes[index++] = (v2 << 6 | v3 << 1 | v4 >>> 4) & 255;
|
||||
bytes[index++] = (v4 << 4 | v5 >>> 1) & 255;
|
||||
bytes[index++] = (v5 << 7 | v6 << 2 | v7 >>> 3) & 255;
|
||||
}
|
||||
return bytes;
|
||||
};
|
||||
|
||||
var encodeAscii = function (str) {
|
||||
var v1, v2, v3, v4, v5, base32Str = '', length = str.length;
|
||||
for (var i = 0, count = parseInt(length / 5) * 5; i < count;) {
|
||||
v1 = str.charCodeAt(i++);
|
||||
v2 = str.charCodeAt(i++);
|
||||
v3 = str.charCodeAt(i++);
|
||||
v4 = str.charCodeAt(i++);
|
||||
v5 = str.charCodeAt(i++);
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
|
||||
BASE32_ENCODE_CHAR[v5 & 31];
|
||||
}
|
||||
|
||||
// remain char
|
||||
var remain = length - count;
|
||||
if (remain === 1) {
|
||||
v1 = str.charCodeAt(i);
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
|
||||
'======';
|
||||
} else if (remain === 2) {
|
||||
v1 = str.charCodeAt(i++);
|
||||
v2 = str.charCodeAt(i);
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
|
||||
'====';
|
||||
} else if (remain === 3) {
|
||||
v1 = str.charCodeAt(i++);
|
||||
v2 = str.charCodeAt(i++);
|
||||
v3 = str.charCodeAt(i);
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
|
||||
'===';
|
||||
} else if (remain === 4) {
|
||||
v1 = str.charCodeAt(i++);
|
||||
v2 = str.charCodeAt(i++);
|
||||
v3 = str.charCodeAt(i++);
|
||||
v4 = str.charCodeAt(i);
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
|
||||
'=';
|
||||
}
|
||||
return base32Str;
|
||||
};
|
||||
|
||||
var encodeUtf8 = function (str) {
|
||||
var v1, v2, v3, v4, v5, code, end = false, base32Str = '',
|
||||
index = 0, i, start = 0, bytes = 0, length = str.length;
|
||||
do {
|
||||
blocks[0] = blocks[5];
|
||||
blocks[1] = blocks[6];
|
||||
blocks[2] = blocks[7];
|
||||
for (i = start; index < length && i < 5; ++index) {
|
||||
code = str.charCodeAt(index);
|
||||
if (code < 0x80) {
|
||||
blocks[i++] = code;
|
||||
} else if (code < 0x800) {
|
||||
blocks[i++] = 0xc0 | (code >> 6);
|
||||
blocks[i++] = 0x80 | (code & 0x3f);
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
blocks[i++] = 0xe0 | (code >> 12);
|
||||
blocks[i++] = 0x80 | ((code >> 6) & 0x3f);
|
||||
blocks[i++] = 0x80 | (code & 0x3f);
|
||||
} else {
|
||||
code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++index) & 0x3ff));
|
||||
blocks[i++] = 0xf0 | (code >> 18);
|
||||
blocks[i++] = 0x80 | ((code >> 12) & 0x3f);
|
||||
blocks[i++] = 0x80 | ((code >> 6) & 0x3f);
|
||||
blocks[i++] = 0x80 | (code & 0x3f);
|
||||
}
|
||||
}
|
||||
bytes += i - start;
|
||||
start = i - 5;
|
||||
if (index === length) {
|
||||
++index;
|
||||
}
|
||||
if (index > length && i < 6) {
|
||||
end = true;
|
||||
}
|
||||
v1 = blocks[0];
|
||||
if (i > 4) {
|
||||
v2 = blocks[1];
|
||||
v3 = blocks[2];
|
||||
v4 = blocks[3];
|
||||
v5 = blocks[4];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
|
||||
BASE32_ENCODE_CHAR[v5 & 31];
|
||||
} else if (i === 1) {
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
|
||||
'======';
|
||||
} else if (i === 2) {
|
||||
v2 = blocks[1];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
|
||||
'====';
|
||||
} else if (i === 3) {
|
||||
v2 = blocks[1];
|
||||
v3 = blocks[2];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
|
||||
'===';
|
||||
} else {
|
||||
v2 = blocks[1];
|
||||
v3 = blocks[2];
|
||||
v4 = blocks[3];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
|
||||
'=';
|
||||
}
|
||||
} while (!end);
|
||||
return base32Str;
|
||||
};
|
||||
|
||||
var encodeBytes = function (bytes) {
|
||||
var v1, v2, v3, v4, v5, base32Str = '', length = bytes.length;
|
||||
for (var i = 0, count = parseInt(length / 5) * 5; i < count;) {
|
||||
v1 = bytes[i++];
|
||||
v2 = bytes[i++];
|
||||
v3 = bytes[i++];
|
||||
v4 = bytes[i++];
|
||||
v5 = bytes[i++];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3 | v5 >>> 5) & 31] +
|
||||
BASE32_ENCODE_CHAR[v5 & 31];
|
||||
}
|
||||
|
||||
// remain char
|
||||
var remain = length - count;
|
||||
if (remain === 1) {
|
||||
v1 = bytes[i];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2) & 31] +
|
||||
'======';
|
||||
} else if (remain === 2) {
|
||||
v1 = bytes[i++];
|
||||
v2 = bytes[i];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4) & 31] +
|
||||
'====';
|
||||
} else if (remain === 3) {
|
||||
v1 = bytes[i++];
|
||||
v2 = bytes[i++];
|
||||
v3 = bytes[i];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1) & 31] +
|
||||
'===';
|
||||
} else if (remain === 4) {
|
||||
v1 = bytes[i++];
|
||||
v2 = bytes[i++];
|
||||
v3 = bytes[i++];
|
||||
v4 = bytes[i];
|
||||
base32Str += BASE32_ENCODE_CHAR[v1 >>> 3] +
|
||||
BASE32_ENCODE_CHAR[(v1 << 2 | v2 >>> 6) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 >>> 1) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v2 << 4 | v3 >>> 4) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v3 << 1 | v4 >>> 7) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 >>> 2) & 31] +
|
||||
BASE32_ENCODE_CHAR[(v4 << 3) & 31] +
|
||||
'=';
|
||||
}
|
||||
return base32Str;
|
||||
};
|
||||
|
||||
var encode = function (input, asciiOnly) {
|
||||
var notString = typeof(input) !== 'string';
|
||||
if (notString && input.constructor === ArrayBuffer) {
|
||||
input = new Uint8Array(input);
|
||||
}
|
||||
if (notString) {
|
||||
return encodeBytes(input);
|
||||
} else if (asciiOnly) {
|
||||
return encodeAscii(input);
|
||||
} else {
|
||||
return encodeUtf8(input);
|
||||
}
|
||||
};
|
||||
|
||||
var decode = function (base32Str, asciiOnly) {
|
||||
if (!asciiOnly) {
|
||||
return toUtf8String(decodeAsBytes(base32Str));
|
||||
}
|
||||
if (!/^[A-Z2-7=]+$/.test(base32Str)) {
|
||||
throw new Error('Invalid base32 characters');
|
||||
}
|
||||
var v1, v2, v3, v4, v5, v6, v7, v8, str = '', length = base32Str.indexOf('=');
|
||||
if (length === -1) {
|
||||
length = base32Str.length;
|
||||
}
|
||||
|
||||
// 8 char to 5 bytes
|
||||
for (var i = 0, count = length >> 3 << 3; i < count;) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v8 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
|
||||
String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
|
||||
String.fromCharCode((v4 << 4 | v5 >>> 1) & 255) +
|
||||
String.fromCharCode((v5 << 7 | v6 << 2 | v7 >>> 3) & 255) +
|
||||
String.fromCharCode((v7 << 5 | v8) & 255);
|
||||
}
|
||||
|
||||
// remain bytes
|
||||
var remain = length - count;
|
||||
if (remain === 2) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255);
|
||||
} else if (remain === 4) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
|
||||
String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255);
|
||||
} else if (remain === 5) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
|
||||
String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
|
||||
String.fromCharCode((v4 << 4 | v5 >>> 1) & 255);
|
||||
} else if (remain === 7) {
|
||||
v1 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v2 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v3 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v4 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v5 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v6 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
v7 = BASE32_DECODE_CHAR[base32Str.charAt(i++)];
|
||||
str += String.fromCharCode((v1 << 3 | v2 >>> 2) & 255) +
|
||||
String.fromCharCode((v2 << 6 | v3 << 1 | v4 >>> 4) & 255) +
|
||||
String.fromCharCode((v4 << 4 | v5 >>> 1) & 255) +
|
||||
String.fromCharCode((v5 << 7 | v6 << 2 | v7 >>> 3) & 255);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
var exports = {
|
||||
encode: encode,
|
||||
decode: decode
|
||||
};
|
||||
decode.asBytes = decodeAsBytes;
|
||||
|
||||
if (COMMON_JS) {
|
||||
module.exports = exports;
|
||||
} else {
|
||||
root.base32 = exports;
|
||||
if (AMD) {
|
||||
define(function() {
|
||||
return exports;
|
||||
});
|
||||
}
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* Identicon.js 2.3.3
|
||||
* http://github.com/stewartlord/identicon.js
|
||||
*
|
||||
* PNGLib required for PNG output
|
||||
* http://www.xarg.org/download/pnglib.js
|
||||
*
|
||||
* Copyright 2018, Stewart Lord
|
||||
* Released under the BSD license
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var PNGlib;
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
PNGlib = require('./pnglib');
|
||||
} else {
|
||||
PNGlib = window.PNGlib;
|
||||
}
|
||||
|
||||
var Identicon = function(hash, options){
|
||||
if (typeof(hash) !== 'string' || hash.length < 15) {
|
||||
throw 'A hash of at least 15 characters is required.';
|
||||
}
|
||||
|
||||
this.defaults = {
|
||||
background: [240, 240, 240, 255],
|
||||
margin: 0.08,
|
||||
size: 64,
|
||||
saturation: 0.7,
|
||||
brightness: 0.5,
|
||||
format: 'png'
|
||||
};
|
||||
|
||||
this.options = typeof(options) === 'object' ? options : this.defaults;
|
||||
|
||||
// backward compatibility with old constructor (hash, size, margin)
|
||||
if (typeof(arguments[1]) === 'number') { this.options.size = arguments[1]; }
|
||||
if (arguments[2]) { this.options.margin = arguments[2]; }
|
||||
|
||||
this.hash = hash
|
||||
this.background = this.options.background || this.defaults.background;
|
||||
this.size = this.options.size || this.defaults.size;
|
||||
this.format = this.options.format || this.defaults.format;
|
||||
this.margin = this.options.margin !== undefined ? this.options.margin : this.defaults.margin;
|
||||
|
||||
// foreground defaults to last 7 chars as hue at 70% saturation, 50% brightness
|
||||
var hue = parseInt(this.hash.substr(-7), 16) / 0xfffffff;
|
||||
var saturation = this.options.saturation || this.defaults.saturation;
|
||||
var brightness = this.options.brightness || this.defaults.brightness;
|
||||
this.foreground = this.options.foreground || this.hsl2rgb(hue, saturation, brightness);
|
||||
};
|
||||
|
||||
Identicon.prototype = {
|
||||
background: null,
|
||||
foreground: null,
|
||||
hash: null,
|
||||
margin: null,
|
||||
size: null,
|
||||
format: null,
|
||||
|
||||
image: function(){
|
||||
return this.isSvg()
|
||||
? new Svg(this.size, this.foreground, this.background)
|
||||
: new PNGlib(this.size, this.size, 256);
|
||||
},
|
||||
|
||||
render: function(){
|
||||
var image = this.image(),
|
||||
size = this.size,
|
||||
baseMargin = Math.floor(size * this.margin),
|
||||
cell = Math.floor((size - (baseMargin * 2)) / 5),
|
||||
margin = Math.floor((size - cell * 5) / 2),
|
||||
bg = image.color.apply(image, this.background),
|
||||
fg = image.color.apply(image, this.foreground);
|
||||
|
||||
// the first 15 characters of the hash control the pixels (even/odd)
|
||||
// they are drawn down the middle first, then mirrored outwards
|
||||
var i, color;
|
||||
for (i = 0; i < 15; i++) {
|
||||
color = parseInt(this.hash.charAt(i), 16) % 2 ? bg : fg;
|
||||
if (i < 5) {
|
||||
this.rectangle(2 * cell + margin, i * cell + margin, cell, cell, color, image);
|
||||
} else if (i < 10) {
|
||||
this.rectangle(1 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
|
||||
this.rectangle(3 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
|
||||
} else if (i < 15) {
|
||||
this.rectangle(0 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
|
||||
this.rectangle(4 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
rectangle: function(x, y, w, h, color, image){
|
||||
if (this.isSvg()) {
|
||||
image.rectangles.push({x: x, y: y, w: w, h: h, color: color});
|
||||
} else {
|
||||
var i, j;
|
||||
for (i = x; i < x + w; i++) {
|
||||
for (j = y; j < y + h; j++) {
|
||||
image.buffer[image.index(i, j)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// adapted from: https://gist.github.com/aemkei/1325937
|
||||
hsl2rgb: function(h, s, b){
|
||||
h *= 6;
|
||||
s = [
|
||||
b += s *= b < .5 ? b : 1 - b,
|
||||
b - h % 1 * s * 2,
|
||||
b -= s *= 2,
|
||||
b,
|
||||
b + h % 1 * s,
|
||||
b + s
|
||||
];
|
||||
|
||||
return[
|
||||
s[ ~~h % 6 ] * 255, // red
|
||||
s[ (h|16) % 6 ] * 255, // green
|
||||
s[ (h|8) % 6 ] * 255 // blue
|
||||
];
|
||||
},
|
||||
|
||||
toString: function(raw){
|
||||
// backward compatibility with old toString, default to base64
|
||||
if (raw) {
|
||||
return this.render().getDump();
|
||||
} else {
|
||||
return this.render().getBase64();
|
||||
}
|
||||
},
|
||||
|
||||
isSvg: function(){
|
||||
return this.format.match(/svg/i)
|
||||
}
|
||||
};
|
||||
|
||||
var Svg = function(size, foreground, background){
|
||||
this.size = size;
|
||||
this.foreground = this.color.apply(this, foreground);
|
||||
this.background = this.color.apply(this, background);
|
||||
this.rectangles = [];
|
||||
};
|
||||
|
||||
Svg.prototype = {
|
||||
size: null,
|
||||
foreground: null,
|
||||
background: null,
|
||||
rectangles: null,
|
||||
|
||||
color: function(r, g, b, a){
|
||||
var values = [r, g, b].map(Math.round);
|
||||
values.push((a >= 0) && (a <= 255) ? a/255 : 1);
|
||||
return 'rgba(' + values.join(',') + ')';
|
||||
},
|
||||
|
||||
getDump: function(){
|
||||
var i,
|
||||
xml,
|
||||
rect,
|
||||
fg = this.foreground,
|
||||
bg = this.background,
|
||||
stroke = this.size * 0.005;
|
||||
|
||||
xml = "<svg xmlns='http://www.w3.org/2000/svg'"
|
||||
+ " width='" + this.size + "' height='" + this.size + "'"
|
||||
+ " style='background-color:" + bg + ";'>"
|
||||
+ "<g style='fill:" + fg + "; stroke:" + fg + "; stroke-width:" + stroke + ";'>";
|
||||
|
||||
for (i = 0; i < this.rectangles.length; i++) {
|
||||
rect = this.rectangles[i];
|
||||
if (rect.color == bg) continue;
|
||||
xml += "<rect "
|
||||
+ " x='" + rect.x + "'"
|
||||
+ " y='" + rect.y + "'"
|
||||
+ " width='" + rect.w + "'"
|
||||
+ " height='" + rect.h + "'"
|
||||
+ "/>";
|
||||
}
|
||||
xml += "</g></svg>"
|
||||
|
||||
return xml;
|
||||
},
|
||||
|
||||
getBase64: function(){
|
||||
if ('function' === typeof btoa) {
|
||||
return btoa(this.getDump());
|
||||
} else if (Buffer) {
|
||||
return new Buffer(this.getDump(), 'binary').toString('base64');
|
||||
} else {
|
||||
throw 'Cannot generate base64 output';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
module.exports = Identicon;
|
||||
} else {
|
||||
window.Identicon = Identicon;
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="959.000000pt" height="1280.000000pt" viewBox="0 0 959.000000 1280.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.15, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1280.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M5740 12793 c-315 -16 -675 -71 -1059 -159 l-153 -36 -174 16 c-1241
|
||||
116 -2270 -197 -3051 -929 -305 -287 -582 -664 -788 -1075 -442 -881 -610
|
||||
-1981 -460 -3000 8 -52 19 -162 25 -245 23 -316 81 -619 191 -1005 451 -1577
|
||||
1668 -3739 2895 -5145 306 -351 708 -728 968 -910 544 -379 913 -398 1476 -76
|
||||
1133 646 2610 2687 3432 4741 428 1068 604 2010 495 2642 -11 60 -11 81 0 118
|
||||
34 117 47 281 47 605 0 480 -45 886 -150 1360 -232 1039 -688 1862 -1331 2397
|
||||
-611 508 -1428 751 -2363 701z m60 -968 c1125 -70 1854 -289 2357 -708 456
|
||||
-380 594 -797 698 -2112 54 -680 72 -1384 45 -1745 -45 -619 -179 -997 -437
|
||||
-1241 -187 -176 -409 -269 -823 -344 -382 -69 -672 -183 -725 -285 -42 -81 51
|
||||
-215 159 -227 101 -11 126 -45 107 -141 -21 -107 -127 -300 -226 -412 -110
|
||||
-125 -219 -181 -408 -211 -105 -16 -407 -6 -614 20 -236 31 -1357 221 -1367
|
||||
232 -2 2 -9 407 -15 899 -21 1586 -39 1989 -106 2375 -56 324 -138 513 -303
|
||||
705 -226 261 -265 316 -245 349 20 33 62 42 246 50 245 12 279 29 236 118 -34
|
||||
70 -337 363 -486 470 -529 379 -1530 543 -2120 347 -117 -39 -191 -82 -259
|
||||
-149 -67 -67 -104 -143 -104 -218 0 -112 117 -147 305 -90 243 73 583 -5 986
|
||||
-227 272 -150 495 -317 715 -535 167 -165 253 -274 314 -398 68 -139 72 -230
|
||||
10 -291 -30 -30 -33 -31 -123 -30 -115 1 -175 22 -375 136 -79 44 -189 100
|
||||
-245 123 -433 178 -901 149 -1262 -80 -76 -48 -270 -243 -358 -360 -91 -121
|
||||
-127 -195 -127 -258 0 -85 60 -126 232 -158 101 -19 576 -22 928 -5 184 9 477
|
||||
21 651 27 504 19 660 -7 736 -120 41 -61 48 -105 48 -321 0 -177 -3 -220 -23
|
||||
-314 -56 -261 -148 -453 -294 -614 -112 -123 -195 -269 -242 -422 -85 -279
|
||||
-26 -500 134 -500 97 0 216 94 280 221 40 79 48 89 65 83 21 -9 42 -71 55
|
||||
-169 17 -128 9 -473 -13 -541 -30 -91 -92 -152 -184 -181 -65 -21 -286 -29
|
||||
-364 -14 -397 79 -930 482 -1021 774 -26 83 -24 95 26 143 53 51 135 92 281
|
||||
142 121 41 137 58 72 79 -65 22 -154 32 -412 48 -406 24 -580 62 -783 170
|
||||
-277 148 -453 423 -537 839 -59 297 -78 552 -78 1076 1 1311 153 2210 478
|
||||
2837 124 238 241 398 421 574 275 268 497 372 949 448 308 51 872 99 1565 131
|
||||
124 6 248 12 275 13 179 11 1096 5 1305 -8z m-4345 -6575 c199 -164 320 -276
|
||||
635 -585 157 -154 326 -310 375 -347 208 -155 438 -242 730 -277 472 -57 626
|
||||
-55 1135 10 430 55 474 60 670 66 357 11 621 -31 915 -146 76 -29 87 -31 220
|
||||
-31 338 0 594 50 788 153 171 91 306 211 607 537 357 387 549 552 615 526 46
|
||||
-17 -9 -188 -131 -410 -135 -244 -261 -439 -639 -986 -386 -559 -677 -1004
|
||||
-790 -1210 -117 -212 -288 -442 -554 -745 -118 -135 -753 -816 -757 -812 -1 1
|
||||
22 128 52 282 77 399 86 461 85 625 0 228 -40 402 -131 577 -55 105 -204 305
|
||||
-283 380 -108 102 -159 81 -332 -137 -151 -190 -241 -355 -314 -575 -53 -159
|
||||
-69 -242 -82 -410 -17 -233 -35 -285 -97 -285 -70 0 -223 123 -482 387 -672
|
||||
682 -1145 1246 -1527 1818 -202 303 -314 514 -395 739 -115 322 -249 591 -365
|
||||
734 -19 23 -66 67 -104 98 -38 30 -73 64 -79 75 -15 27 2 47 43 52 18 2 38 5
|
||||
45 5 8 1 74 -48 147 -108z"/>
|
||||
<path d="M7110 10000 c-549 -51 -1000 -178 -1275 -359 -84 -55 -188 -151 -254
|
||||
-235 -132 -166 -122 -232 56 -354 215 -148 226 -207 59 -326 -119 -85 -203
|
||||
-203 -213 -299 -5 -46 -2 -57 19 -82 89 -103 462 30 792 283 32 25 122 106
|
||||
199 180 292 279 602 470 999 613 298 107 552 137 728 84 179 -54 295 -20 307
|
||||
88 17 146 -135 273 -412 347 -176 47 -323 62 -625 65 -157 2 -328 -1 -380 -5z"/>
|
||||
<path d="M7087 8399 c-471 -39 -976 -290 -1106 -550 -57 -113 -34 -233 52
|
||||
-283 313 -182 1661 -220 2272 -65 193 49 295 129 295 232 0 91 -114 231 -275
|
||||
339 -263 176 -605 293 -959 327 -120 12 -135 12 -279 0z"/>
|
||||
<path d="M5564 5951 c-76 -19 -73 -45 14 -130 174 -171 493 -377 666 -430 115
|
||||
-35 176 -22 176 40 0 91 -145 281 -290 379 -79 54 -210 116 -285 135 -61 16
|
||||
-225 19 -281 6z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
|
@ -0,0 +1,23 @@
|
|||
function toHexString(byteArray) {
|
||||
// cc-by-sa-4 https://stackoverflow.com/a/44608819 by https://stackoverflow.com/users/1883624/grantpatterson
|
||||
var s = '0x';
|
||||
byteArray.forEach(function(byte) {
|
||||
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
|
||||
});
|
||||
return s;
|
||||
}
|
||||
|
||||
function userIcon(pubkey, imgSize=64){
|
||||
pubkey = toHexString(base32.decode.asBytes(pubkey))
|
||||
let options = {
|
||||
//foreground: [0,0,0,1], // rgba black
|
||||
background: [255, 255, 255, 255], // rgba white
|
||||
//margin: 0.1,
|
||||
size: imgSize,
|
||||
format: 'svg' // use SVG instead of PNG
|
||||
};
|
||||
|
||||
// create a base64 encoded SVG
|
||||
let data = new Identicon(pubkey, options).toString();
|
||||
return data
|
||||
}
|
Loading…
Reference in New Issue