前段时间在尝试使用不同的语言使用到腾讯的 tc-tea 实现,因此造了一堆轮子。
最开始写的是 C++ 实现,后来改为纯 C 版本,此后根据需要改写了 Rust、Go、JS、PHP 版本。
因为 TEA 的块大小刚好是 8 字节,因此在移植到 Rust 的时候开始尝试使用 u64
来表示其状态。
C
纯 C 语言的实现,GitHub 仓库。
需要自行管理内存,用起来相对麻烦。
Rust
纯 Rust 语言的实现。GitHub 仓库 | crates.io。
加入到 Cargo.toml
的 [dependencies]
中:
tc_tea = "0.2"
使用:
use tc_tea;
fn hello_tc_tea() {
let key = b"12345678ABCDEFGH";
let encrypted = tc_tea::encrypt(&"hello", &key).unwrap();
let decrypted = tc_tea::decrypt(&encrypted, &key).unwrap();
assert_eq!("hello", std::str::from_utf8(&decrypted).unwrap());
}
Go
纯 Go 语言的实现。GitHub 仓库。
从 Rust 代码移植过来。因为申请内存很方便,这个实现会申请新的内存空间来存储返回数据。
go get github.com/jixunmoe-go/[email protected]
使用案例:
package main
import (
"bytes"
"github.com/jixunmoe-go/tc_tea"
"log"
)
func main() {
key := []byte("12345678ABCDEFGH")
encrypted, err := tc_tea.Encrypt([]byte("hello world"), key)
if err != nil {
log.Fatal(err)
}
decrypted, err := tc_tea.Decrypt(encrypted, key)
if err != nil {
log.Fatal(err)
}
if !bytes.Equal(decrypted, []byte("hello world")) {
log.Fatal("decrypted != []byte(\"hello world\")")
}
}
JavaScript
TypeScript 的实现,支持 Node,带类型提示。GitHub 仓库。
没有原生 u64
类型支持,因此使用的还是 Uint8Array
来存储数据。
安装:
npm i tc_tea
使用:
import assert from 'node:assert';
import { decrypt } from 'tc_tea';
const fromHex = (str: string) => Uint8Array.from(Array.from(str.matchAll(/../g), (x) => parseInt(x[0], 16)));
const decoder = new TextDecoder();
const data = fromHex('86ebcc7fa8a354f03fa7575e160b2d09c2238ccc13345a9d');
const result = decoder.decode(decrypt(data, '12345678ABCDEFGH'));
assert.strictEqual('hello world', result);
PHP
不太懂 PHP 怎么发包,留了一份 gist 了。
PHP 的整形类型有点奇怪,因此内部都是用 string
类型来表示。属于“能用”的状态。
使用方法:
<?php
require_once 'tc_tea.php';
$d1 = \TC_TEA\ecb_decrypt("\x56\x27\x6b\xa9\x80\xb9\xec\x16", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00");
var_dump(bin2hex($d1));
assert($d1 === "\x01\x02\x03\x04\x05\x06\x07\x08");
mt_srand();
for ($i = 0; $i < 1000; $i++) {
$v = \TC_TEA\decrypt(\TC_TEA\encrypt("wowowowow", "12345678ABCDEFGH"), "12345678ABCDEFGH");
assert($v === "wowowowow");
}
$decrypted = \TC_TEA\decrypt(hex2bin("86ebcc7fa8a354f03fa7575e160b2d09c2238ccc13345a9d"), "12345678ABCDEFGH");
var_dump($decrypted);