mirror of
				https://git.coolaj86.com/coolaj86/browser-authenticator.js
				synced 2025-11-04 02:12:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			143 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
Copyright (c) 2011, Chris Umbel
 | 
						|
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
						|
of this software and associated documentation files (the "Software"), to deal
 | 
						|
in the Software without restriction, including without limitation the rights
 | 
						|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
						|
copies of the Software, and to permit persons to whom the Software is
 | 
						|
furnished to do so, subject to the following conditions:
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
						|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
						|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
						|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
						|
THE SOFTWARE.
 | 
						|
*/
 | 
						|
(function (exports) {
 | 
						|
'use strict';
 | 
						|
 | 
						|
var charTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
 | 
						|
var byteTable = [
 | 
						|
    0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 | 
						|
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 | 
						|
    0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
 | 
						|
    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
 | 
						|
    0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
 | 
						|
    0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
 | 
						|
    0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
 | 
						|
    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
 | 
						|
    0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
 | 
						|
    0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff
 | 
						|
];
 | 
						|
 | 
						|
function quintetCount(buff) {
 | 
						|
    var quintets = Math.floor(buff.length / 5);
 | 
						|
    return buff.length % 5 === 0 ? quintets: quintets + 1;
 | 
						|
}
 | 
						|
 | 
						|
exports.bufferToBase32 = function(plain) {
 | 
						|
    // plain MUST come in either as Array or Uint8Array
 | 
						|
    if('undefined' !== typeof Uint8Array) {
 | 
						|
        if (!(plain instanceof Uint8Array)){
 | 
						|
            plain = new Uint8Array(plain);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    var i = 0;
 | 
						|
    var j = 0;
 | 
						|
    var shiftIndex = 0;
 | 
						|
    var digit = 0;
 | 
						|
    var encoded = new Array(quintetCount(plain) * 8);
 | 
						|
 | 
						|
    /* byte by byte isn't as pretty as quintet by quintet but tests a bit
 | 
						|
        faster. will have to revisit. */
 | 
						|
    while(i < plain.length) {
 | 
						|
        var current = plain[i];
 | 
						|
 | 
						|
        if(shiftIndex > 3) {
 | 
						|
            digit = current & (0xff >> shiftIndex);
 | 
						|
            shiftIndex = (shiftIndex + 5) % 8;
 | 
						|
            digit = (digit << shiftIndex) | ((i + 1 < plain.length) ?
 | 
						|
                plain[i + 1] : 0) >> (8 - shiftIndex);
 | 
						|
            i++;
 | 
						|
        } else {
 | 
						|
            digit = (current >> (8 - (shiftIndex + 5))) & 0x1f;
 | 
						|
            shiftIndex = (shiftIndex + 5) % 8;
 | 
						|
            if(shiftIndex === 0) { i++; }
 | 
						|
        }
 | 
						|
 | 
						|
        encoded[j] = charTable[digit];
 | 
						|
        j++;
 | 
						|
    }
 | 
						|
 | 
						|
    for(i = j; i < encoded.length; i++) {
 | 
						|
        encoded[i] = '=';
 | 
						|
    }
 | 
						|
 | 
						|
    return encoded.join('');
 | 
						|
};
 | 
						|
 | 
						|
exports.base32ToBuffer = function(encoded) {
 | 
						|
    var shiftIndex = 0;
 | 
						|
    var plainDigit = 0;
 | 
						|
    var plainChar;
 | 
						|
    var plainPos = 0;
 | 
						|
    var len = Math.ceil(encoded.length * 5 / 8);
 | 
						|
    var decoded;
 | 
						|
    encoded = encoded.split('').map(function (ch) {
 | 
						|
      return ch.charCodeAt(0);
 | 
						|
    });
 | 
						|
    if('undefined' !== typeof Uint8Array) {
 | 
						|
        encoded = new Uint8Array(encoded);
 | 
						|
        decoded = new Uint8Array(len);
 | 
						|
    } else {
 | 
						|
        decoded = new Array(len);
 | 
						|
    }
 | 
						|
 | 
						|
    /* byte by byte isn't as pretty as octet by octet but tests a bit
 | 
						|
        faster. will have to revisit. */
 | 
						|
    for(var i = 0; i < encoded.length; i++) {
 | 
						|
        if(encoded[i] === 0x3d){ //'='
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        var encodedByte = encoded[i] - 0x30;
 | 
						|
 | 
						|
        if(encodedByte < byteTable.length) {
 | 
						|
            plainDigit = byteTable[encodedByte];
 | 
						|
 | 
						|
            if(shiftIndex <= 3) {
 | 
						|
                shiftIndex = (shiftIndex + 5) % 8;
 | 
						|
 | 
						|
                if(shiftIndex === 0) {
 | 
						|
                    plainChar |= plainDigit;
 | 
						|
                    decoded[plainPos] = plainChar;
 | 
						|
                    plainPos++;
 | 
						|
                    plainChar = 0;
 | 
						|
                } else {
 | 
						|
                    plainChar |= 0xff & (plainDigit << (8 - shiftIndex));
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                shiftIndex = (shiftIndex + 5) % 8;
 | 
						|
                plainChar |= 0xff & (plainDigit >>> shiftIndex);
 | 
						|
                decoded[plainPos] = plainChar;
 | 
						|
                plainPos++;
 | 
						|
 | 
						|
                plainChar = 0xff & (plainDigit << (8 - shiftIndex));
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            throw new Error('Invalid input - it is not base32 encoded string');
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (decoded.slice) { // Array or TypedArray
 | 
						|
      return decoded.slice(0, plainPos);
 | 
						|
    } else { // Mobile Safari TypedArray
 | 
						|
      return new Uint8Array(Array.prototype.slice.call(decoded, 0, plainPos));
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
}(window.Unibabel || window));
 |