apotocki/dataforge
GitHub: apotocki/dataforge
一个 C++20 header-only 数据转换 pipeline 库,将编码、哈希、加密、压缩与 Unicode 转换等操作统一为可组合的声明式链路。
Stars: 1 | Forks: 1
[](https://github.com/apotocki/dataforge/actions/workflows/msvc-tests.yml)
[](https://github.com/apotocki/dataforge/actions/workflows/linux-tests.yml)
[](https://github.com/apotocki/dataforge/actions/workflows/macos-tests.yml)
# DataForge
**DataForge** 是一个现代的 C++20 header-only 库,用于构建声明式、可组合的数据转换 pipeline。
它同时提供了基于 push(输出)和 pull(输入)iterator 的接口,用于应用任意链路的转换,包括编码、解码、压缩、加密、哈希和 Unicode 操作。
转换过程使用 *quarks* 来描述——这是一种小巧、可组合的对象,可以通过 `|` 运算符串联在一起。
## 快速示例
```
#include "dataforge/quark_push_iterator.hpp"
#include "dataforge/quark_pull_iterator.hpp"
#include "dataforge/base_xx/base64.hpp"
using namespace dataforge;
std::string input = "Hello, World!";
std::string base64_result;
// Create a pipeline: input bytes → Base64 encoding → output
auto push_it = quark_push_iterator(int8 | base64, std::back_inserter(base64_result));
*push_it = input;
push_it.finish();
std::cout << "Encoded: " << base64_result << std::endl; // Output: SGVsbG8sIFdvcmxkIQ==
// Reverse the process: Base64 → decoded bytes
std::string decoded_result;
auto pull_it = quark_pull_iterator(base64 | int8, base64_result);
for (auto span = *pull_it; !span.empty(); span = *++pull_it) {
std::copy(span.begin(), span.end(), std::back_inserter(decoded_result));
}
std::cout << "Decoded: " << decoded_result << std::endl; // Output: Hello, World!
```
**更复杂的 pipeline** 可以串联多种转换:
```
// Example: text → UTF-8 → compression → encryption → Base64
auto pipeline = utf8 | deflated() | aes(128, key) | base64;
```
## 为什么 DataForge 独一无二
与其他仅涵盖部分功能的库不同,DataForge 在一个一致的框架内整合了多种类型的数据转换。
| 功能 / 特性 | DataForge | Crypto++ | Boost | ICU | range-v3 |
|-------------------------------|:---------:|:--------:|:----:|:---:|:--------:|
| Integer ↔ Bytes + Endian | ✅ | ❌ | ❌ | ❌ | ❌ |
| base16/32/58/64/ascii85/z85 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 自定义 Base 1 < N < 256 | ✅ | ❌ | ❌ | ❌ | ❌ |
| Checksums (crc, adler, bsd) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Hashes (MD, SHA, Blake, 等)| ✅ | ✅ | ❌ | ❌ | ❌ |
| 加密 / 解密 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 压缩 / 解压缩 | ✅ | ❌ | ❌ | ❌ | ❌ |
| Unicode 转换 (UTF) | ✅ | ❌ | ❌ | ✅ | ❌ |
| ICU 字符集转换 | ✅ | ❌ | ❌ | ✅ | ❌ |
| Grapheme 分割 | ✅ | ❌ | ❌ | ✅ | ❌ |
| Header-only | ✅ | ❌ | ✅ | ❌ | ✅ |
| Push/Pull iterator pipeline | ✅ | ❌ | ✅ (filters) | ❌ | ✅ |
**关键点:** DataForge 允许在一个声明式 pipeline 中串联各种转换,例如 integer → endian → compression → encryption → base encoding。
## 核心功能
### 1. Integer ↔ Byte sequence 转换(包含 endianness)
- 将各种大小的 integer 序列转换为 byte sequence,或反向转换。
- 可配置为 **little-endian** 或 **big-endian** 表示。
### 2. 编码 / 解码
- **Base16, Base32, Base58, Base64, ASCII85, Z85**。
- 支持 `1 < N < 256` 的任意进制转换及自定义字母表——这实际上是一种进制系统转换。
### 3. Checksums
- BSD checksum
- Adler32
- CRC8, CRC16, CRC32, CRC64
### 4. Hash 函数
- MD2, MD4, MD5, MD6
- RIPEMD, Tiger
- SHA1, SHA2, SHA3
- Belt, GOST, Streebog, Whirlpool, Blake
### 5. 加密 / 解密
- RC2, RC4, RC5, RC6
- DES, AES, Blowfish
- Belt, Magma
### 6. 压缩 / 解压缩
- Deflate
- Bzip2
- LZ4
- LZMA, LZMA2
*(需要相应的外部库)*
### 7. Unicode 编码转换
- UTF-7, UTF-8, UTF-16, UTF-32
### 8. 基于 ICU 的字符串编码转换
- [ICU 库](https://icu.unicode.org/) 支持的任何编码
*(需要 ICU 库)*
### 9. Grapheme Breaker
- 根据 [Unicode Standard](https://unicode.org/reports/tr29/) 将 Unicode 字符串分割成 grapheme。
## 运行测试的安装说明
该库本身是 **header-only** 的——在你的项目中使用时无需构建任何内容。
然而,测试套件依赖于外部库(**zlib, icu, bzip2, lz4, liblzma, gtest**),这些库通过 [vcpkg](https://github.com/microsoft/vcpkg) 进行管理。
### 构建和运行测试的步骤:
1. 在你系统的任意位置**安装 vcpkg**(如果尚未安装)。
2. 将环境变量 `VCPKG_ROOT` **设置**为你的 vcpkg 安装路径。
- 示例:
setx VCPKG_ROOT "C:\dev\vcpkg"
3. 打开测试用的 Visual Studio 解决方案并进行构建。
- 在首次构建时:
- 项目将自动:
1. 检查是否设置了 `VCPKG_ROOT`。
2. 运行:
$(VCPKG_ROOT)\vcpkg.exe install
这会将 `vcpkg.json` 中所有必需的依赖项安装到本地的 `vcpkg_installed` 文件夹中。
3. 配置 `INCLUDE` 和 `LIB` 路径以使用这些本地安装的依赖项。
4. 从 Visual Studio 运行测试。
**不需要全局的 vcpkg 集成 (`vcpkg integrate install`)**——一切都是局限于该代码库本地的。
## 硬件加速
**SHA-1** 和 **SHA-2** 系列支持在编译时选择硬件加速的 block 处理。
所有变体始终具有可移植的标量回退方案,因此加速永远不会改变结果——只会影响吞吐量。
### 加速配置
一个单独的宏 `DATAFORGE_ACCEL_PROFILE` 可以为**所有**加速算法选择 ISA 级别。通过 `-DDATAFORGE_ACCEL_PROFILE=` 进行设置:
| 值 | 名称 | 描述 |
|------:|------|-------------|
| `-1` | `AUTO` *(默认)* | 运行时 CPU 检测——在首次使用时通过 CPUID / `getauxval` 选择最佳 backend,并在进程的生命周期内缓存。 |
| `0` | `SCALAR` | 纯 C++——无 ISA 内联函数。可在任何地方编译和运行。 |
| `1` | `X86_SHA_NI` | x86 强制:SHA-1/224/256 使用 SHA-NI + SSE4.1;SHA-512 系列使用 SSE4.1。无运行时探测——CPU **必须**支持这些指令。 |
| `2` | `X86_AVX512` | x86 强制:SHA-1/224/256 使用 SHA-NI + AVX-512 消息调度适用于**所有** SHA-2 变体,包括 SHA-224/256。CPU **必须**支持 AVX-512F/VL。 |
| `3` | `ARM_NEON` | AArch64 强制:NEON 向量化的 SHA-512 消息调度;SHA-1/224/256 使用标量。可在**任何** AArch64 CPU 上运行。 |
| `4` | `ARM_SHA` | AArch64 强制:SHA-1/224/256 使用 SHA2 加密扩展;SHA-384/512 使用 NEON。需要 `HWCAP_SHA2`(例如 Cortex-A53+crypto, A55, A57…)。 |
| `5` | `ARM_CRYPTO` | AArch64 强制:SHA-1/224/256 使用 SHA2 加密扩展,**并且** SHA-384/512 使用 SHA-512 硬件扩展。同时需要 `HWCAP_SHA2` 和 `HWCAP_SHA512`(ARMv8.2-A+sha3,例如 Cortex-A55 rev≥1, Apple M-series, Neoverse)。 |
### Backends
#### SHA-1
- **x86 SHA-NI** — Intel SHA Extensions (`_mm_sha1rnds4` / `_mm_sha1nexte` /
`_mm_sha1msg1` / `_mm_sha1msg2`)。SHA-1 最快的单 block 路径。
由 `X86_SHA_NI`、`X86_AVX512` 和 `AUTO`(当 CPUID 检测到 SHA 时)使用。
- **ARM SHA1** — AArch64 加密扩展 (`vsha1cq` / `vsha1pq` / `vsha1mq` /
`vsha1su0q` / `vsha1su1q`)。由 `ARM_CRYPTO` 和 `AUTO`(当
`getauxval(AT_HWCAP)` 中设置了 `HWCAP_SHA1` 时)使用。
#### SHA-2 (224 / 256)
- **x86 SHA-NI** — Intel SHA Extensions (`_mm_sha256rnds2` / `msg1` / `msg2`)。
最快的单 block 路径。由 `X86_SHA_NI`、`X86_AVX512` 和 `AUTO` 使用。
- **x86 AVX-512** — SHA-224/256 的向量化消息调度 (AVX-512F + AVX-512VL, `vprord`)。
仅由 `X86_AVX512` 使用(SHA-NI 的单 block 处理速度更快,因此在 `AUTO` 模式下,该系列永远不会选择它)。
- **ARM SHA2** — AArch64 加密扩展 (`vsha256hq` / `vsha256su*`)。
由 `ARM_CRYPTO` 和 `AUTO`(当存在 `HWCAP_SHA2` 时)使用。
#### SHA-2 (384 / 512 / 512-224 / 512-256)
- **x86 AVX-512** — 使用 `vprorq`(64 位通道旋转)的向量化消息调度,8 倍展开压缩。
由 `X86_AVX512` 和 `AUTO`(当 AVX-512F/VL 可用且 OS 已通过 `XCR0` 启用寄存器状态时)使用。
- **x86 SSE4.1** — 相同的双宽 XMM 调度,但 64 位旋转被分解为移位-或对。
由 `X86_SHA_NI` 和 `AUTO`(当 AVX-512 不可用时)使用。
自 2008 年以来,几乎所有 x86-64 硬件都具备此功能。
- **ARM SHA-512** — ARMv8.2-A 扩展 (`vsha512hq` / `vsha512h2q` /
`vsha512su0q` / `vsha512su1q`)。由 `ARM_CRYPTO` 和 `AUTO`(当
`getauxval(AT_HWCAP2)` 中设置了 `HWCAP2_SHA512` 时)使用。
- **ARM NEON** — 使用基准 NEON 64 位通道操作(移位-或对)的向量化消息调度。
在**所有 AArch64** CPU(Cortex-A53 及更高版本)上可用。
由 `ARM_NEON`、`ARM_CRYPTO`(在缺少 SHA-512 扩展时作为回退)和
`AUTO`(当缺少 SHA-512 扩展时)使用。
在 GCC/Clang 上,每个 backend 的内联函数通过
`__attribute__((target(...)))` 实现按函数启用,因此在*构建*它们时
不需要全局的 `-msha` / `-mavx512*` /
`-march=armv8-a+sha2` / `-march=armv8.2-a+sha3` 标志;
而在 MSVC 上,它们始终可用。
### `AUTO` 如何选择 backend
| 算法 | x86 | AArch64 |
|-----------|-----|---------|
| SHA-1 | SHA-NI → 标量 | SHA1 加密扩展 → 标量 |
| SHA-224/256 | SHA-NI → 标量 | SHA2 加密扩展 → 标量 |
| SHA-384/512/… | AVX-512 → SSE4.1 → 标量 | SHA-512 扩展 → NEON → 标量 |
### CMake / 编译器示例
```
# 默认(自动检测)
cmake -S . -B build
# 到处强制使用 scalar
cmake -S . -B build -DDATAFORGE_ACCEL_PROFILE=0
# 强制使用 x86 SHA-NI + SSE4.1 (profile 1)
cmake -S . -B build -DDATAFORGE_ACCEL_PROFILE=1
# 对所有 SHA-2 强制使用 x86 AVX-512,包括 SHA-224/256 (profile 2)
cmake -S . -B build -DDATAFORGE_ACCEL_PROFILE=2
# 对 SHA-512 强制使用 AArch64 NEON,对 SHA-1/256 强制使用 scalar (profile 3)
cmake -S . -B build -DDATAFORGE_ACCEL_PROFILE=3
# 强制使用 AArch64 crypto extensions (SHA2 + SHA-512) (profile 4)
cmake -S . -B build -DDATAFORGE_ACCEL_PROFILE=4
```
不使用 CMake(直接定义编译器宏):
```
g++ ... -DDATAFORGE_ACCEL_PROFILE=2
```
## License
基于 [Boost Software License, Version 1.0](_URL_6/>) 分发。
标签:Bash脚本, C++, 密码学, 开发组件, 手动系统调用, 数据擦除, 算法库, 编解码