@@ -13,6 +13,8 @@ const bip39 = require('bip39') // https://github.com/bitcoinjs/bip39 // 有更
const hdkey = require ( 'hdkey' ) // https://github.com/cryptocoinjs/hdkey // 或者用 bitcore-mnemonic 或者 ethers 里的相同功能
const hdkey = require ( 'hdkey' ) // https://github.com/cryptocoinjs/hdkey // 或者用 bitcore-mnemonic 或者 ethers 里的相同功能
// const bitcorelib = require('bitcore-lib')
// const bitcorelib = require('bitcore-lib')
const secp256k1 = require ( 'secp256k1' )
const secp256k1 = require ( 'secp256k1' )
const base32encode = require ( 'base32-encode' )
const base32decode = require ( 'base32-decode' )
// 全部以hex为默认输入输出格式,方便人的阅读,以及方便函数之间统一接口
// 全部以hex为默认输入输出格式,方便人的阅读,以及方便函数之间统一接口
@@ -182,7 +184,7 @@ class TICrypto {
// eccrypto 能用 Uint8Array 和 Buffer
// eccrypto 能用 Uint8Array 和 Buffer
// eccrypto-js 只能用 Buffer
// eccrypto-js 只能用 Buffer
// 在浏览器里 https://github.com/bitchan/eccrypto 库报错,即使用了 Uint8Array: Failed to execute 'encrypt' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'
// 在浏览器里 https://github.com/bitchan/eccrypto 库报错,即使用了 Uint8Array: Failed to execute 'encrypt' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'
let cipherobject = await eccrypto . encrypt ( Buffer . from ( this . hex2buf ( key ) ) , data )
let cipherobject = await eccrypto . encrypt ( Buffer . from ( this . hex _to _buf ( key ) ) , data )
return cipherobject // 返回一个复杂的结构 {iv:Buffer, ciphertext:Buffer, ...}。对同样的key和data,每次返回的结果不一样
return cipherobject // 返回一个复杂的结构 {iv:Buffer, ciphertext:Buffer, ...}。对同样的key和data,每次返回的结果不一样
} else if ( keytype === 'pwd' ) {
} else if ( keytype === 'pwd' ) {
// 对称加密
// 对称加密
@@ -190,7 +192,7 @@ class TICrypto {
let inputEncoding = my . INPUT _LIST . indexOf ( input ) >= 0 ? input : my . INPUT // 'utf8' by default, 'ascii', 'latin1' for string or ignored for Buffer/TypedArray/DataView
let inputEncoding = my . INPUT _LIST . indexOf ( input ) >= 0 ? input : my . INPUT // 'utf8' by default, 'ascii', 'latin1' for string or ignored for Buffer/TypedArray/DataView
let outputEncoding = output === 'buf' ? undefined : my . OUTPUT _LIST . indexOf ( output ) >= 0 ? output : my . OUTPUT // 'latin1', 'base64', 'hex' by default or 'buf' to Buffer explicitly
let outputEncoding = output === 'buf' ? undefined : my . OUTPUT _LIST . indexOf ( output ) >= 0 ? output : my . OUTPUT // 'latin1', 'base64', 'hex' by default or 'buf' to Buffer explicitly
const iv = crypto . randomBytes ( 16 )
const iv = crypto . randomBytes ( 16 )
let encryptor = crypto . createCipheriv ( my . CIPHER _LIST . indexOf ( cipher ) >= 0 ? cipher : my . CIPHER , this . hex2buf ( this . hash ( key ) ) , iv ) // cipher 和 key 的长度必须相同,例如 cipher 是 ***-192,那么 key 就必须是 192/8=24 字节 = 48 hex 的。
let encryptor = crypto . createCipheriv ( my . CIPHER _LIST . indexOf ( cipher ) >= 0 ? cipher : my . CIPHER , this . hex _to _buf ( this . hash ( key ) ) , iv ) // cipher 和 key 的长度必须相同,例如 cipher 是 ***-192,那么 key 就必须是 192/8=24 字节 = 48 hex 的。
if ( typeof data !== 'string' && ! ( data instanceof Buffer ) && ! ( data instanceof DataView ) ) data = JSON . stringify ( data )
if ( typeof data !== 'string' && ! ( data instanceof Buffer ) && ! ( data instanceof DataView ) ) data = JSON . stringify ( data )
let ciphertext = encryptor . update ( data , inputEncoding , outputEncoding )
let ciphertext = encryptor . update ( data , inputEncoding , outputEncoding )
ciphertext += encryptor . final ( outputEncoding ) // 但是 Buffer + Buffer 还是会变成string
ciphertext += encryptor . final ( outputEncoding ) // 但是 Buffer + Buffer 还是会变成string
@@ -198,10 +200,10 @@ class TICrypto {
}
}
} else if ( keytype === 'seckey' ) {
} else if ( keytype === 'seckey' ) {
// 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeypairs() 生成的 rsa 公私钥
// 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥,只能用 crypto.generateKeypairs() 生成的 rsa 公私钥
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
return crypto . privateEncrypt ( seckeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果都一样。
return crypto . privateEncrypt ( seckeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果都一样。
} else if ( keytype === 'pubkey' ) {
} else if ( keytype === 'pubkey' ) {
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' )
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' )
return crypto . publicEncrypt ( pubkeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果不一样。
return crypto . publicEncrypt ( pubkeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果不一样。
}
}
return null
return null
@@ -220,7 +222,7 @@ class TICrypto {
// data 应当是 encrypt 输出的数据类型
// data 应当是 encrypt 输出的数据类型
if ( tool === 'eccrypto' ) {
if ( tool === 'eccrypto' ) {
try {
try {
// eccrypto 只能接受 Buffer, 不接受 Uint8Array, 因为 eccrypto 需要调用 Buffer.compare 方法,不能在这里直接用 hex2 buf
// eccrypto 只能接受 Buffer, 不接受 Uint8Array, 因为 eccrypto 需要调用 Buffer.compare 方法,不能在这里直接用 hex_to_ buf
// eccrypto 也只能接受 Buffer, 不接受 Uint8Array
// eccrypto 也只能接受 Buffer, 不接受 Uint8Array
// data 需要是 eccrypto 自身encrypt方法返回的 cipherobject. key 是 private key。
// data 需要是 eccrypto 自身encrypt方法返回的 cipherobject. key 是 private key。
let plainbuffer = await eccrypto . decrypt ( Buffer . from ( key , 'hex' ) , data ) // 返回的是 Buffer
let plainbuffer = await eccrypto . decrypt ( Buffer . from ( key , 'hex' ) , data ) // 返回的是 Buffer
@@ -236,7 +238,7 @@ class TICrypto {
let outputEncoding = output === 'buf' ? undefined : my . INPUT _LIST . indexOf ( output ) >= 0 ? output : my . INPUT // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly
let outputEncoding = output === 'buf' ? undefined : my . INPUT _LIST . indexOf ( output ) >= 0 ? output : my . INPUT // output (=input of encrypt) could be 'latin1', 'ascii', 'utf8' by default or 'buf' to Buffer explicitly
let decryptor = crypto . createDecipheriv (
let decryptor = crypto . createDecipheriv (
my . CIPHER _LIST . indexOf ( cipher ) >= 0 ? cipher : my . CIPHER ,
my . CIPHER _LIST . indexOf ( cipher ) >= 0 ? cipher : my . CIPHER ,
this . hex2buf ( this . hash ( key ) ) ,
this . hex _to _buf ( this . hash ( key ) ) ,
Buffer . from ( data . iv , 'hex' )
Buffer . from ( data . iv , 'hex' )
)
)
let decrypted = decryptor . update ( data . ciphertext , inputEncoding , outputEncoding )
let decrypted = decryptor . update ( data . ciphertext , inputEncoding , outputEncoding )
@@ -246,10 +248,10 @@ class TICrypto {
}
}
} else if ( keytype === 'seckey' ) {
} else if ( keytype === 'seckey' ) {
// 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥
// 尚未走通,不能使用 ticCrypto 生成的 Elliptic curve 椭圆曲线算法公私钥
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
return crypto . privateDecrypt ( seckeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果都一样。
return crypto . privateDecrypt ( seckeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果都一样。
} else if ( keytype === 'pubkey' ) {
} else if ( keytype === 'pubkey' ) {
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' )
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( key ) , { namedCurve : 'P-256K' } ) . export ( 'pem' )
return crypto . publicDecrypt ( pubkeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果不一样。
return crypto . publicDecrypt ( pubkeyPEM , Buffer . from ( data ) ) // 返回 Buffer。每次结果不一样。
}
}
return null
return null
@@ -279,7 +281,7 @@ class TICrypto {
return signature . toString ( 'hex' )
return signature . toString ( 'hex' )
} else if ( seckey . length === 64 ) {
} else if ( seckey . length === 64 ) {
// 纯 crypto
// 纯 crypto
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( seckey ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
let seckeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( seckey ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 私钥导出的der格式为144字节。
let signer = crypto . createSign ( my . HASHER _LIST . indexOf ( hasher ) >= 0 ? hasher : my . HASHER ) // 注意,不知为何,hasher必须含有'sha'才能完成签名,例如 sha1, sha256, sha512, sha3, RSA-SHA1, id-rsassa-pkcs1-v1_5-with-sha3-224, 其他都会报错。
let signer = crypto . createSign ( my . HASHER _LIST . indexOf ( hasher ) >= 0 ? hasher : my . HASHER ) // 注意,不知为何,hasher必须含有'sha'才能完成签名,例如 sha1, sha256, sha512, sha3, RSA-SHA1, id-rsassa-pkcs1-v1_5-with-sha3-224, 其他都会报错。
signer . update ( this . hash ( data ) ) . end ( )
signer . update ( this . hash ( data ) ) . end ( )
let signature = signer . sign ( seckeyPEM , 'hex' )
let signature = signer . sign ( seckeyPEM , 'hex' )
@@ -322,7 +324,7 @@ class TICrypto {
}
}
} else if ( signature . length >= 140 ) {
} else if ( signature . length >= 140 ) {
// 纯 crypto // 发现大小写不影响 crypto 验签!都能通过
// 纯 crypto // 发现大小写不影响 crypto 验签!都能通过
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex2buf ( pubkey ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 公钥导出的der格式为88字节。经测试,同一对压缩和非压缩公钥得出的结果一模一样。
let pubkeyPEM = await new keyman . Key ( 'oct' , this . hex _to _buf ( pubkey ) , { namedCurve : 'P-256K' } ) . export ( 'pem' ) // 公钥导出的der格式为88字节。经测试,同一对压缩和非压缩公钥得出的结果一模一样。
let verifier = crypto . createVerify ( my . HASHER _LIST . indexOf ( hasher ) >= 0 ? hasher : my . HASHER )
let verifier = crypto . createVerify ( my . HASHER _LIST . indexOf ( hasher ) >= 0 ? hasher : my . HASHER )
verifier . update ( this . hash ( data ) ) . end ( ) // end() 在 nodejs 12 里返回verifier自身,但在浏览器里返回 undefined,因此不能串联运行。
verifier . update ( this . hash ( data ) ) . end ( ) // end() 在 nodejs 12 里返回verifier自身,但在浏览器里返回 undefined,因此不能串联运行。
let verified = verifier . verify ( pubkeyPEM , signature , 'hex' ) // 如果给signature添加1位hex, crypto 的 verify结果也是true! 估计因为一位hex不被转成字节。但减少1位会导致false
let verified = verifier . verify ( pubkeyPEM , signature , 'hex' ) // 如果给signature添加1位hex, crypto 的 verify结果也是true! 估计因为一位hex不被转成字节。但减少1位会导致false
@@ -554,13 +556,13 @@ class TICrypto {
curve = my . CURVE _LIST . indexOf ( curve ) >= 0 ? curve : my . CURVE // 默认为 secp256k1
curve = my . CURVE _LIST . indexOf ( curve ) >= 0 ? curve : my . CURVE // 默认为 secp256k1
// return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes')
// return new crypto.createECDH(curve).setPrivateKey(seckey,'hex').getPublicKey('hex', compress===false?'uncompressed':'compressed') // ecdh.getPublicKey(不加参数) 默认为 'compressed'。用 HBuilderX 2.6.4 打包成ios或安卓 app 后 setPrivateKey() 报错:TypeError: null is not an object (evaluating 'this.rand.getBytes')
// 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。
// 从 nodejs 10.0 开始,还有 crypto.ECDH.convertKey 方法,更直接。但可惜,浏览器里不存在 crypto.ECDH。
return this . buf2hex ( secp256k1 . publicKeyCreate ( Buffer . from ( seckey , 'hex' ) , compress !== false ) ) // 可用于浏览器。缺省输出压缩公钥,compress=false时输出非压缩公钥。
return this . buf _to _hex ( secp256k1 . publicKeyCreate ( Buffer . from ( seckey , 'hex' ) , compress !== false ) ) // 可用于浏览器。缺省输出压缩公钥,compress=false时输出非压缩公钥。
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(seckey)).toString('hex') // 可用于浏览器
// 或者 bitcorelib.PublicKey.fromPrivateKey(new bitcorelib.PrivateKey(seckey)).toString('hex') // 可用于浏览器
// 或者 const ecc = require('eccrypto')
// 或者 const ecc = require('eccrypto')
// if (compress===false){
// if (compress===false){
// return ecc.getPublic(this.hex2 buf(seckey)).toString('hex')
// return ecc.getPublic(this.hex_to_ buf(seckey)).toString('hex')
// }else{
// }else{
// return ecc.getPublicCompressed(this.hex2 buf(seckey)).toString('hex')
// return ecc.getPublicCompressed(this.hex_to_ buf(seckey)).toString('hex')
// }
// }
// 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(seckey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
// 注意,Buffer.from(nacl.box.keyPair.fromSecretKey(Buffer.from(seckey,'hex')).publicKey).toString('hex') 得到的公钥与上面的不同
} else if ( this . isSeckey ( seckey ) && seckey . length === 128 ) {
} else if ( this . isSeckey ( seckey ) && seckey . length === 128 ) {
@@ -685,7 +687,7 @@ class TICrypto {
address = bs58check . encode ( Buffer . from ( prefix + position , 'hex' ) ) // wallet import format
address = bs58check . encode ( Buffer . from ( prefix + position , 'hex' ) ) // wallet import format
return address
return address
} else {
} else {
// 默认为 TIC。把纯位置转换为大小写敏感能自我验证的 b64u(base64 for url) 地址。
// 默认为 TIC。把纯位置转换为大小写敏感能自我验证的 b64t 地址。
let prefix
let prefix
switch ( world ) {
switch ( world ) {
// Base64: https://baike.baidu.com/item/base64
// Base64: https://baike.baidu.com/item/base64
@@ -702,8 +704,8 @@ class TICrypto {
prefix = '4c'
prefix = '4c'
}
}
let checksum = this . hash ( this . hash ( prefix + position ) ) . slice ( 0 , 6 ) // 添加 checksum 使得能够检测大小写错误。[todo] 校验码里要不要包含 prefix?
let checksum = this . hash ( this . hash ( prefix + position ) ) . slice ( 0 , 6 ) // 添加 checksum 使得能够检测大小写错误。[todo] 校验码里要不要包含 prefix?
// address = this.hex2 eip55(prefix + position + checksum) // 前缀1节,位置20节,校验3节,共24节=48字符(能够完全转化为8个色彩),再转eip55。
// address = this.hex_to_ eip55(prefix + position + checksum) // 前缀1节,位置20节,校验3节,共24节=48字符(能够完全转化为8个色彩),再转eip55。
address = this . hex2b64u ( prefix + position + checksum ) // 实际采用 b64u (named by luk.lu as base 64 for url) , 共 32字符。
address = this . hex _to _b64t ( prefix + position + checksum ) // 实际采用 b64t , 共 32字符。
return address
return address
}
}
return null
return null
@@ -722,13 +724,13 @@ class TICrypto {
// todo: 如果是大小写敏感的,进行有效性验证
// todo: 如果是大小写敏感的,进行有效性验证
return address . toLowerCase ( )
return address . toLowerCase ( )
} else if ( /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,34}$/ . test ( address ) ) { // BTC
} else if ( /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,34}$/ . test ( address ) ) { // BTC
let hex = this . b58c2hex ( address )
let hex = this . b58c _to _hex ( address )
if ( hex ) {
if ( hex ) {
return hex . slice ( 2 ) // 去除网络前缀
return hex . slice ( 2 ) // 去除网络前缀
}
}
} else if ( /^[Tt][0-9a-zA-Z\._]{31}$/ . test ( address ) ) { // TIC
} else if ( /^[Tt][0-9a-zA-Z\._]{31}$/ . test ( address ) ) { // TIC
// 格式合法
// 格式合法
let hex = this . b64u2hex ( address )
let hex = this . b64t _to _hex ( address )
let [ all , prefix , position , checksum ] = hex . match ( /^([\da-fA-F]{2})([\da-fA-F]{40})([\da-fA-F]{6})$/ )
let [ all , prefix , position , checksum ] = hex . match ( /^([\da-fA-F]{2})([\da-fA-F]{40})([\da-fA-F]{6})$/ )
if ( this . hash ( this . hash ( position ) ) . slice ( 0 , 6 ) === checksum ) {
if ( this . hash ( this . hash ( position ) ) . slice ( 0 , 6 ) === checksum ) {
return position
return position
@@ -750,13 +752,13 @@ class TICrypto {
return 'ETH'
return 'ETH'
} else if ( /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,34}$/ . test ( address ) && address . length !== 32 ) {
} else if ( /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,34}$/ . test ( address ) && address . length !== 32 ) {
// 格式合法。常见的是 33或34字符长度
// 格式合法。常见的是 33或34字符长度
let prefixedPosition = this . b58c2hex ( address )
let prefixedPosition = this . b58c _to _hex ( address )
if ( prefixedPosition && prefixedPosition . length === 42 )
if ( prefixedPosition && prefixedPosition . length === 42 )
// 内容合法
// 内容合法
return 'BTC'
return 'BTC'
} else if ( /^[Ttd][0-9a-zA-Z\._]{31}$/ . test ( address ) ) {
} else if ( /^[Ttd][0-9a-zA-Z\._]{31}$/ . test ( address ) ) {
// 格式合法
// 格式合法
let hex = Buffer . from ( this . b64u _to _b64 ( address ) , 'base64' ) . toString ( 'hex' )
let hex = Buffer . from ( this . b64t _to _b64 ( address ) , 'base64' ) . toString ( 'hex' )
let [ all , prefix , position , checksum ] = hex . match ( /^([\da-fA-F]{2})([\da-fA-F]{40})([\da-fA-F]{6})$/ ) // 内容合法
let [ all , prefix , position , checksum ] = hex . match ( /^([\da-fA-F]{2})([\da-fA-F]{40})([\da-fA-F]{6})$/ ) // 内容合法
if ( this . hash ( this . hash ( prefix + position ) ) . slice ( 0 , 6 ) === checksum )
if ( this . hash ( this . hash ( prefix + position ) ) . slice ( 0 , 6 ) === checksum )
// [todo] 校验码里要不要包含 prefix?
// [todo] 校验码里要不要包含 prefix?
@@ -1181,7 +1183,7 @@ class TICrypto {
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static buf2hex ( buffer ) {
static buf _to _hex ( buffer ) {
// buffer is an ArrayBuffer
// buffer is an ArrayBuffer
return Array . prototype . map . call ( new Uint8Array ( buffer ) , ( x ) => ( '00' + x . toString ( 16 ) ) . slice ( - 2 ) ) . join ( '' )
return Array . prototype . map . call ( new Uint8Array ( buffer ) , ( x ) => ( '00' + x . toString ( 16 ) ) . slice ( - 2 ) ) . join ( '' )
}
}
@@ -1194,7 +1196,7 @@ class TICrypto {
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static hex2buf ( hex ) {
static hex _to _buf ( hex ) {
return new Uint8Array (
return new Uint8Array (
hex . match ( /[\da-f]{2}/gi ) . map ( function ( h ) {
hex . match ( /[\da-f]{2}/gi ) . map ( function ( h ) {
return parseInt ( h , 16 )
return parseInt ( h , 16 )
@@ -1213,7 +1215,7 @@ class TICrypto {
* bs58check 和 bs58 可接受string, Buffer, ArrayBuffer, Array (包括空字符串'', 各种内容的数组例如包含 undefined, {...},等等);
* bs58check 和 bs58 可接受string, Buffer, ArrayBuffer, Array (包括空字符串'', 各种内容的数组例如包含 undefined, {...},等等);
* 不可接受 undefined, null, {...}, 等等,会返回 exception
* 不可接受 undefined, null, {...}, 等等,会返回 exception
*/
*/
static hex2b58c ( hex ) {
static hex _to _b58c ( hex ) {
try {
try {
return bs58check . encode ( Buffer . from ( hex , 'hex' ) )
return bs58check . encode ( Buffer . from ( hex , 'hex' ) )
} catch ( exception ) {
} catch ( exception ) {
@@ -1221,7 +1223,7 @@ class TICrypto {
}
}
}
}
static hex2b58 ( hex ) {
static hex _to _b58 ( hex ) {
try {
try {
return bs58 . encode ( Buffer . from ( hex , 'hex' ) )
return bs58 . encode ( Buffer . from ( hex , 'hex' ) )
} catch ( exception ) {
} catch ( exception ) {
@@ -1237,7 +1239,7 @@ class TICrypto {
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static b58c2hex ( box ) {
static b58c _to _hex ( box ) {
try {
try {
return bs58check . decode ( box ) . toString ( 'hex' )
return bs58check . decode ( box ) . toString ( 'hex' )
} catch ( exception ) {
} catch ( exception ) {
@@ -1245,7 +1247,7 @@ class TICrypto {
}
}
}
}
static b582hex ( box ) {
static b58 _to _hex ( box ) {
try {
try {
return bs58 . decode ( box ) . toString ( 'hex' )
return bs58 . decode ( box ) . toString ( 'hex' )
} catch ( exception ) {
} catch ( exception ) {
@@ -1256,45 +1258,71 @@ class TICrypto {
/**
/**
* b64 字符串为 a-zA-Z0-9+/
* b64 字符串为 a-zA-Z0-9+/
* 其中,+ 和 / 会在 url query string 里被转成 %2B 和 %2F
* 其中,+ 和 / 会在 url query string 里被转成 %2B 和 %2F
* 因此定义 b64u (base64 for url ),用 . 和 _ 替换。
* 因此定义 b64t (base64 for tic ),用 . 和 _ 替换。
* (为何不用 -,因为 - 和空格一样导致 css white-space 自动换行。)
* (为何不用 base64url, 因为 base64url 把 + 变成 - 和空格一样导致 css white-space 自动换行。)
* @param {*} b64
* @param {*} b64
* @returns
* @returns
*/
*/
static b64 _to _b64u ( b64 = '' ) {
static b64 _to _b64t ( b64 = '' ) {
return b64 . replace ( /\+/g , '.' ) . replace ( /\//g , '_' ) . replace ( /=/g , '' )
return b64 . replace ( /\+/g , '.' ) . replace ( /\//g , '_' ) . replace ( /=/g , '' )
}
}
static b64u _to _b64 ( b64u = '' ) {
static b64t _to _b64 ( b64t = '' ) {
return b64u . replace ( /\./g , '+' ) . replace ( /_/g , '/' )
return b64t . replace ( /\./g , '+' ) . replace ( /_/g , '/' )
}
}
/**
/**
* 十六进制转b64u
* 十六进制转b64t
*
*
* @static
* @static
* @param {*} hex
* @param {*} hex
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static hex2b64u ( hex ) {
static hex _to _b64t ( hex ) {
if ( /^[0-9a-fA-F]+$/ . test ( hex ) ) {
if ( /^[0-9a-fA-F]+$/ . test ( hex ) ) {
return this . b64 _to _b64u ( Buffer . from ( hex , 'hex' ) . toString ( 'base64' ) )
return this . b64 _to _b64t ( Buffer . from ( hex , 'hex' ) . toString ( 'base64' ) )
}
}
return null
return null
}
}
/**
/**
* b64u 转16进制
* b64t 转16进制
*
*
* @static
* @static
* @param {*} b64u
* @param {*} b64t
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static b64u2hex ( b64u ) {
static b64t _to _hex ( b64t ) {
if ( /^[0-9a-zA-Z\._]+$/ . test ( b64u ) ) {
if ( /^[0-9a-zA-Z\._]+$/ . test ( b64t ) ) {
return Buffer . from ( this . b64u _to _b64 ( b64u ) , 'base64' ) . toString ( 'hex' )
return Buffer . from ( this . b64t _to _b64 ( b64t ) , 'base64' ) . toString ( 'hex' )
}
return null
}
// https://en.wikipedia.org/wiki/Base32
static hex _to _b32 ( hex , { encoding = 'RFC4648' } = { } ) {
if ( /^[0-9a-fA-F]+$/ . test ( hex ) ) {
return base32encode ( Buffer . from ( hex , 'hex' ) , encoding )
}
return null
}
static b32 _to _hex ( b32 , { encoding = 'RFC4648' } = { } ) {
if ( /^[A-Za-z2-7=]+$/ . test ( b32 ) ) {
return Buffer . from ( base32decode ( b32 . toUpperCase ( ) , encoding ) ) . toString ( 'hex' )
}
return null
}
static hex _to _b32h ( hex , { encoding = 'RFC4648-HEX' } = { } ) {
if ( /^[0-9a-fA-F]+$/ . test ( hex ) ) {
return base32encode ( Buffer . from ( hex , 'hex' ) , encoding )
}
return null
}
static b32h _to _hex ( b32 , { encoding = 'RFC4648-HEX' } = { } ) {
if ( /^[0-9A-Va-v=]+$/ . test ( b32 ) ) {
return Buffer . from ( base32decode ( b32 . toUpperCase ( ) , encoding ) ) . toString ( 'hex' )
}
}
return null
return null
}
}
@@ -1307,8 +1335,8 @@ class TICrypto {
* @return {*}
* @return {*}
* @memberof TICrypto
* @memberof TICrypto
*/
*/
static hex2eip55 ( hex ) {
static hex _to _eip55 ( hex ) {
if ( /^(0x)?[\da-fA-F]* $/ . test ( hex ) ) {
if ( /^(0x)?[\da-fA-F]+ $/ . test ( hex ) ) {
hex = hex . toLowerCase ( ) . replace ( '0x' , '' )
hex = hex . toLowerCase ( ) . replace ( '0x' , '' )
let hash = keccak ( 'keccak256' ) . update ( hex ) . digest ( 'hex' )
let hash = keccak ( 'keccak256' ) . update ( hex ) . digest ( 'hex' )
let result = ''
let result = ''