Created
April 23, 2017 17:25
-
-
Save Creased/ab49828928039769f3de2e16a2b04310 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Author: Baptiste MOINE <[email protected]> | |
* Project: OTP QR-Code Generator | |
* Homepage: https://vps.bmoine.fr/totp-qrcode/ | |
* Released: 17/04/2017 | |
* | |
* Based on http://www.herongyang.com/Encoding/Base32-Encoding-Algorithm.html | |
* | |
* Base32 encoding process: | |
* 0. Get input string + remove carriage return and new line; | |
* 1. Parse bytes from input string; | |
* 2. Add padding to divide input bytes to 5-bytes blocks; | |
* 3. Create 5-bits groups; | |
* 4. Map each group to one printable character based on the Base32 character set; | |
* 5. Override characters that aren't based on the input string, but padding; | |
* 6. (Facultative) Add padding to create 8-chars blocks; | |
* 7. Return the encoded string. | |
*/ | |
function b32encode(str, padding) { | |
var opts = { | |
'alphabet': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', | |
'pad': '=', | |
'padding': (padding === true) && true || false | |
}, | |
str = str && str.toString().split('\r')[0].split('\n')[0] || ''; // 0 | |
var left = str.length % 5; // 5 | |
// 1 | |
var out = (function(str) { | |
var bits = []; | |
for (var i = 0; i < str.length; ++i) { | |
bits[i] = ('000000000' + (str[i].charCodeAt(0).toString(2))).substr(-8); | |
} | |
return bits; | |
})(str.split('')); | |
// 2 | |
out = (function(bits) { | |
var len = bits.length, | |
pad = '00000000'; | |
var left = 5 - (len % 5); | |
if (left < 5) { | |
for (var i = 0; i < left; ++i) { | |
bits[len + i] = pad; | |
} | |
} | |
return bits; | |
})(out); | |
// 3 | |
out = (function(bits) { | |
var len = bits.length, | |
parts = []; | |
for (var i = 0; i < len; ++i) { | |
var j = Math.floor((i / 5)); | |
parts[j] = parts[j] && parts[j].toString() || ''; | |
parts[j] += bits[i]; | |
} | |
return parts; | |
})(out.join('')); | |
// 4 | |
out = (function(bits, alphabet) { | |
var alphabet = alphabet && alphabet.toString() || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', | |
len = bits.length; | |
for (var i = 0; i < len; ++i) { | |
var j = parseInt(bits[i], 2); | |
bits[i] = alphabet[j]; | |
} | |
return bits; | |
})(out, opts.alphabet); | |
// 5 | |
var override = 0; | |
switch (left) { | |
case 1: | |
override = 6; | |
break; | |
case 2: | |
override = 4 | |
break; | |
case 3: | |
override = 3; | |
break; | |
case 4: | |
override = 1; | |
break; | |
} | |
for (var i = 0; i < override; ++i) { | |
out.pop(); | |
} | |
// 6 | |
if (opts.padding) { | |
for (i = 0; i < override; ++i) { | |
out.push(opts.pad); | |
} | |
} | |
return out.join(''); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment