base64改用原生实现

master
yutent 2024-05-29 12:23:04 +08:00
parent b9ba7c1f4e
commit 97400afb39
5 changed files with 29 additions and 138 deletions

View File

@ -1,3 +1,4 @@
src/ src/
test/
build.js build.js
.prettierrc.yaml .prettierrc.yaml

View File

@ -1,6 +1,6 @@
{ {
"name": "crypto.web.js", "name": "crypto.web.js",
"version": "1.0.5", "version": "1.0.6",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",
"files": [ "files": [

View File

@ -1,141 +1,28 @@
import { str2uint, buf2str } from './helper.js' import { encode, decode } from './helper.js'
var lookup = [] // string 转 binary
var revLookup = [] function str2bin(str) {
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array let bin = ''
let u8 = encode(str) // 转成Uint8Array
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for (let i = 0; i < u8.length; i++) {
for (var i = 0, len = code.length; i < len; ++i) { bin += String.fromCharCode(u8[i])
lookup[i] = code[i] }
revLookup[code.charCodeAt(i)] = i return bin
} }
// Support decoding URL-safe base64 strings, as Node.js does. function bin2str(b) {
// See: https://en.wikipedia.org/wiki/Base64#URL_applications let u8 = new Uint8Array(b.length)
revLookup['-'.charCodeAt(0)] = 62 for (let i = 0; i < u8.length; i++) {
revLookup['_'.charCodeAt(0)] = 63 u8[i] = b[i].charCodeAt(0)
function getLens(b64) {
var len = b64.length
// 补足 =
while (len % 4 > 0) {
b64 += '='
len++
} }
return decode(u8)
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len
var placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4)
return [validLen, placeHoldersLen]
}
// base64 is 4/3 + up to two characters of the original data
function byteLength(b64) {
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen
}
function _byteLength(b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen
}
function toByteArray(b64) {
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
var curByte = 0
// if there are placeholders, only get up to the last complete 4 chars
var len = placeHoldersLen > 0 ? validLen - 4 : validLen
var i
for (i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xff
arr[curByte++] = (tmp >> 8) & 0xff
arr[curByte++] = tmp & 0xff
}
if (placeHoldersLen === 2) {
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xff
}
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xff
arr[curByte++] = tmp & 0xff
}
return arr
}
function tripletToBase64(num) {
return (
lookup[(num >> 18) & 0x3f] +
lookup[(num >> 12) & 0x3f] +
lookup[(num >> 6) & 0x3f] +
lookup[num & 0x3f]
)
}
function encodeChunk(uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff)
output.push(tripletToBase64(tmp))
}
return output.join('')
}
function fromByteArray(uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==')
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=')
}
return parts.join('')
} }
// 支持对中文的base64编码 // 支持对中文的base64编码
export function base64encode(str) { export function base64encode(str) {
return fromByteArray(str2uint(str)) return btoa(str2bin(str))
} }
export function base64decode(str) { export function base64decode(str) {
return buf2str(toByteArray(str)) return bin2str(atob(base64))
} }

View File

@ -1,4 +1,4 @@
import { str2uint, getType } from './helper.js' import { encode, getType } from './helper.js'
const subtle = window.crypto.subtle const subtle = window.crypto.subtle
@ -20,11 +20,11 @@ function any2uint(data) {
case 'Number': case 'Number':
case 'String': case 'String':
case 'Boolean': case 'Boolean':
val = str2uint(val) val = encode(val)
break break
default: default:
val = val.toString() val = encode(val.toString())
break break
} }
return val return val
@ -85,10 +85,10 @@ export function sha512(str) {
return hash('SHA-512', str) return hash('SHA-512', str)
} }
export function hmac(mode, data = '', key = '', encode) { export function hmac(mode, data = '', key = '', encoding) {
if (key) { if (key) {
if (typeof key === 'string') { if (typeof key === 'string') {
key = str2uint(key) key = encode(key)
} }
} else { } else {
key = new Uint8Array(16) key = new Uint8Array(16)
@ -99,7 +99,7 @@ export function hmac(mode, data = '', key = '', encode) {
.then(ab => { .then(ab => {
var output = ab var output = ab
switch (encode) { switch (encoding) {
case 'binary': case 'binary':
output = ab2bin(ab) output = ab2bin(ab)
break break

View File

@ -4,11 +4,14 @@ const decoder = new TextDecoder()
/** /**
* String Uint8Array * String Uint8Array
*/ */
export function str2uint(txt) { export function encode(txt) {
return encoder.encode(txt) return encoder.encode(txt)
} }
export function buf2str(buf) { /**
* Uint8Array String
*/
export function decode(buf) {
return decoder.decode(buf) return decoder.decode(buf)
} }