工具包 tools
tools 是三层同一实现的纯 JS 工具包,挂在三个全局变量上:wadLogicLayer.tools、wadRenderLayer.tools、wadPanelLayer.tools。三层拿到的是同一份源码构建出的对象,已知向量完全一致。
所有函数都是同步的,输入支持 string | ArrayBuffer | Uint8Array(哈希/编码类),输出为 string 或 Uint8Array。
本页你将学到
- 哈希、编码、随机、数据处理四类工具的用法;
- 写死在文档里的自检锚点(可用来验证环境);
- tools 在网络改写里的两个实战。
md5(d) / sha1(d) / sha256(d)
哈希,返回小写 hex。
js
wadPanelLayer.tools.md5('abc')
// '900150983cd24fb0d6963f7d28e17f72'
wadPanelLayer.tools.sha1('abc')
// 'a9993e364706816aba3e25717850c26c9cd0d89d'
wadPanelLayer.tools.sha256('abc')
// 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
// 字节输入与字符串输入结果一致
wadPanelLayer.tools.md5(wadPanelLayer.tools.utf8.encode('abc'))
// '900150983cd24fb0d6963f7d28e17f72'hmacSha256(key, data)
标准 HMAC-SHA256,返回 64 位小写 hex。
js
wadPanelLayer.tools.hmacSha256('key', 'The quick brown fox jumps over the lazy dog')
// 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'
// 典型场景:给请求加签名
const sign = wadPanelLayer.tools.hmacSha256(secret, timestamp + body);
req.header['x-sign'] = sign;crc32(d)
返回 8 位小写 hex(补零)。
js
wadPanelLayer.tools.crc32('abc') // '352441c2'
wadPanelLayer.tools.crc32(new Uint8Array([1, 2, 3]))base64 / base64url / hex / utf8 / url
编码与解码五件套:
| 方法 | 说明 |
|---|---|
base64.encode(s) / decode(s) / decodeText(s) | decode 返回 Uint8Array;decodeText 直接出 UTF-8 字符串 |
base64url.encode / decode | URL 安全变体(+→-、/→_、去 =),解码自动兼容两种形式 |
hex.encode / decode | hex ↔ Uint8Array |
utf8.encode / decode | UTF-8 ↔ Uint8Array/字符串 |
url.encode / decode | encodeURIComponent/decodeURIComponent 包装 |
js
wadPanelLayer.tools.base64.encode('abc') // 'YWJj'
wadPanelLayer.tools.base64.decode('YWJj') // Uint8Array(3) [97, 98, 99]
wadPanelLayer.tools.base64.decodeText('aGVsbG8h') // 'hello!'(解码 + UTF-8 还原,一步到位)
wadPanelLayer.tools.base64url.encode(wadPanelLayer.tools.utf8.encode('a?b/c')) // 'YT9iL2M'
wadPanelLayer.tools.hex.encode(wadPanelLayer.tools.hex.decode('deadbeef')) // 'deadbeef'(往返)
const bytes = wadPanelLayer.tools.utf8.encode('中文abc~'); // Uint8Array
wadPanelLayer.tools.utf8.decode(bytes) // '中文abc~'
wadPanelLayer.tools.url.encode('a b&c=d') // 'a%20b%26c%3Dd'uuid() / randomBytes(n)
随机与标识。
js
wadPanelLayer.tools.uuid()
// '3f2504e0-4f89-41d3-9a0c-0305e82c3301'(RFC 4122 v4)
const salt = wadPanelLayer.tools.randomBytes(16); // Uint8Array(16),优先密码学随机源deepClone(o)
JSON 深拷贝(不可序列化的值原样返回)。不会修改原对象。
js
const o = { a: { b: [1, { c: 'x' }] } };
const c = wadPanelLayer.tools.deepClone(o);
c.a.b[1].c = 'y';
o.a.b[1].c // 仍是 'x'get(o, path, def) / set(o, path, value)
点路径读写,get 支持默认值。
js
wadPanelLayer.tools.get(o, 'a.b.1.c') // 'x'
wadPanelLayer.tools.get(o, 'nope.z', 'dft') // 'dft'
wadPanelLayer.tools.set({}, 'x.y', 5) // { x: { y: 5 } }(中间节点自动创建)typeOf(v) / isArrayBuffer(v) / isPlainObject(v)
类型判断。typeOf 比 typeof 更细:区分 array / arraybuffer / typedarray / null / undefined。
js
wadPanelLayer.tools.typeOf(null) // 'null'
wadPanelLayer.tools.typeOf(new ArrayBuffer(2)) // 'arraybuffer'
wadPanelLayer.tools.typeOf(new Uint8Array(2)) // 'typedarray'
wadPanelLayer.tools.typeOf([]) // 'array'
wadPanelLayer.tools.typeOf(1) // 'number'
wadPanelLayer.tools.isArrayBuffer(new ArrayBuffer(1)) // true
wadPanelLayer.tools.isPlainObject({}) // true
wadPanelLayer.tools.isPlainObject([]) // false
wadPanelLayer.tools.isPlainObject(new Date()) // false三层同一实现
三个全局变量上的 tools 行为完全一致:
js
wadLogicLayer.tools.md5('abc') === wadPanelLayer.tools.md5('abc') // true(同一实现)实战:给改写 hook 里的二进制做校验
js
// capture.intercept 响应 hook:对二进制响应做 crc32 完整性标记
wadLogicLayer.capture.intercept.response(function (resp) {
if (resp.data instanceof ArrayBuffer) {
resp.header = resp.header || {};
resp.header['x-wad-crc32'] = wadLogicLayer.tools.crc32(resp.data);
return resp;
}
});实战:签名请求
js
const body = JSON.stringify(payload);
const ts = String(Date.now());
const sign = wadPanelLayer.tools.hmacSha256(APP_SECRET, ts + body);
wadPanelLayer.http.request({
url: 'https://api.example.com/push',
method: 'POST',
header: { 'content-type': 'application/json', 'x-ts': ts, 'x-sign': sign },
data: body,
});