WebAssembly 部署
前往Release 页面下载编译好的 WebAssembly .wasm 文件。
然后,推荐使用 wasmtime 来调用它,其他 Runtime 不做特别兼容。
本项目的 WebAssembly 模块使用 Javy 编译而来,方便在 C++、Rust、Go 等语言中调用,不推荐在类似 Python、 Java、Node.js 的解释器中调用。
要调用本 WebAssembly 模块,需要使用尚在预览状态的 WASI,目前仅有 wasmtime 提供了最完整的 WASI 支持,但它在各个语言的实现并不一致。
本模块的合法输入为一个 JSON 字符串,输入时请勿附带注释,遵循以下格式:
{
"method":"", // WENYAN | OLD | BEAR
"inputType":"", // TEXT | UINT8
"outputType":"", // TEXT | UINT8
"input":"", // 输入的数据,如果是TEXT请直接输入纯文本,如果是任意字节,请输入Base64编码字符串
"mode":"", // ENCRYPT | DECRYPT | AUTO // AUTO 仅在 method 指定 OLD 时合法
"key":"", // 加密密钥,一个字符串 //如果缺省,自动使用默认值
"q":bool, // OLD模式下,决定是否添加标志位
"WenyanConfig":{...}, //文言文生成配置,详情见JavaScript接口定义。
"AdvancedEncConfig":{...} //高级加密配置,详情见JavaScript接口定义。
}输出格式
WASM 模块执行完毕后,结果将通过 stdout 以纯文本形式输出。
- 如果
outputType指定为UINT8,则输出的是 Base64 编码字符串(或 Base64 字符串数组)。 - 如果开启了高级加密的
FlexibleTransfer灵活分段功能,输出可能是一个字符串数组(或 Base64 字符串数组)。
安全性和性能警告
此 WASM 模块将 JS 代码和 QuickJS 运行时捆绑在一起,允许你在有 wasmtime 的环境中调用模块。你需要注意以下事项。
执行效率将显著劣于 V8 引擎环境,尤其是执行密集哈希运算的时候。
QuickJS是轻量化的 JS 运行时,无法和 V8 媲美。QuickJS不支持获取密码学安全随机数,因此,随机数算法将由梅森旋转作为代替。这会导致加密安全性被削弱。
WASM 不是魔曰的主线开发任务,依赖库未经积极更新,如果遇到问题,请提 Issue。
如果 WASM 的使用场景过少,它最终会被移除。
用 wasmtime CLI 调用,在不同的命令行里有不同的方式,大多数时候是输入字符串的字符集的区别,以及是否需要在字符串外面加单引号的区别。
在 Windows CMD 或者 Powershell 中调用,请确保执行了 chcp 65001 以调整代码页为 UTF-8。
注意在 Windows CMD 中,输入的字符串不需要用单引号囊括。
echo '{"method":"WENYAN","mode":"ENCRYPT","inputType":"TEXT","outputType":"TEXT","input":"愿青空的祝福,与我的羽翼同在","key":"ABRACADABRA","WenyanConfig":{"PianwenMode":true}}' | wasmtime abracadabra-cn.wasm对于其他语言,你需要使用 Wasmtime WASI 的 stdin 和 stdout 接口来操作本模块的输入输出,调用 _start 方法来启动本模块。
下方提供 Python 的示例,其他语言请自行查阅 wasmtime 对应的文档。
pip install wasmtimeimport wasmtime
def run_wasi(wasm_file):
engine = wasmtime.Engine()
module = wasmtime.Module.from_file(engine, wasm_file)
store = wasmtime.Store(engine)
linker = wasmtime.Linker(engine)
wasi = wasmtime.WasiConfig()
#Python 的 wasmtime 实现,想写入stdin,必须使用一个文件。
#文件里填写要输入的JSON。
wasi.stdin_file = "<Path_to_JSON_File>"
wasi.inherit_stdout()
wasi.inherit_stderr()
linker.define_wasi()
store.set_wasi(wasi)
instance = linker.instantiate(store, module)
start = instance.exports(store)["_start"]
start(store)
try:
run_wasi("<Path_to_WASM_Module_File>")
except FileNotFoundError:
print(f"Error: WASM file '{wasm_file}' not found.")
except wasmtime.WasmtimeError as e:
print(f"Wasmtime error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")自行编译 (Javy)
首先,拉取仓库,安装 Javy,配置恰当的环境。
然后,像编译普通 JS 库一样,执行:
npm install
npm run build在输出文件夹中,找到 abracadabra-cn-javy.js
然后用 Javy 在命令行中编译:
javy build "Path/to/abracadabra-cn-javy.js" -o "path/Output.wasm"