sm-crypto
Version:
55 lines (48 loc) • 1.8 kB
JavaScript
const sm3 = require('../sm2/sm3')
/**
* 字节数组转 16 进制串
*/
function ArrayToHex(arr) {
return arr.map(item => {
item = item.toString(16)
return item.length === 1 ? '0' + item : item
}).join('')
}
/**
* utf8 串转字节数组
*/
function utf8ToArray(str) {
const arr = []
for (let i = 0, len = str.length; i < len; i++) {
const point = str.codePointAt(i)
if (point <= 0x007f) {
// 单字节,标量值:00000000 00000000 0zzzzzzz
arr.push(point)
} else if (point <= 0x07ff) {
// 双字节,标量值:00000000 00000yyy yyzzzzzz
arr.push(0xc0 | (point >>> 6)) // 110yyyyy(0xc0-0xdf)
arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
} else if (point <= 0xD7FF || (point >= 0xE000 && point <= 0xFFFF)) {
// 三字节:标量值:00000000 xxxxyyyy yyzzzzzz
arr.push(0xe0 | (point >>> 12)) // 1110xxxx(0xe0-0xef)
arr.push(0x80 | ((point >>> 6) & 0x3f)) // 10yyyyyy(0x80-0xbf)
arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
} else if (point >= 0x010000 && point <= 0x10FFFF) {
// 四字节:标量值:000wwwxx xxxxyyyy yyzzzzzz
i++
arr.push((0xf0 | (point >>> 18) & 0x1c)) // 11110www(0xf0-0xf7)
arr.push((0x80 | ((point >>> 12) & 0x3f))) // 10xxxxxx(0x80-0xbf)
arr.push((0x80 | ((point >>> 6) & 0x3f))) // 10yyyyyy(0x80-0xbf)
arr.push((0x80 | (point & 0x3f))) // 10zzzzzz(0x80-0xbf)
} else {
// 五、六字节,暂时不支持
arr.push(point)
throw new Error('input is not supported')
}
}
return arr
}
module.exports = function (input) {
input = typeof input === 'string' ? utf8ToArray(input) : Array.prototype.slice.call(input)
return ArrayToHex(sm3(input))
}