https://github.com/leiless/base16
A wicked fast RFC4648-conformed Base16 encoder/decoder
https://github.com/leiless/base16
Last synced: over 1 year ago
JSON representation
A wicked fast RFC4648-conformed Base16 encoder/decoder
- Host: GitHub
- URL: https://github.com/leiless/base16
- Owner: leiless
- License: bsd-2-clause
- Created: 2019-04-03T14:35:56.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-04-09T14:02:41.000Z (about 7 years ago)
- Last Synced: 2025-03-15T00:39:52.898Z (over 1 year ago)
- Language: C
- Size: 1.41 MB
- Stars: 1
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## base16 - A wicked fast RFC4648-conformed Base16 encoder/decoder
This Base16 implementation presents a way to optimize base16 encode/decode in linear facet(not significant) without intervention of SIMD instructions, provides a simple example of how `.data` segment cache can boost up data lookup.
# Encode APIs
There're three encode methods:
```c
void nano_base16_encode_baseline(char * restrict, const void * restrict, size_t);
void nano_base16_encode(char * restrict, const void * restrict, size_t);
void nano_base16_encode2(char * restrict, const void * restrict, size_t);
```
### Which API should I choose for encode?
TL;DR. `nano_base16_encode`
`nano_base16_encode_baseline` uses definition-intuitive way for encoding.
`nano_base16_encode` which encoding in a manner of taking a byte as a whole, which each time produce two encoded characters in an atomic way, with negligible(1kb) `.data` segment overhead.
`nano_base16_encode2` encode in a manner of taking two bytes as a whole, which each time produce four encoded characters in an atomic way, with relative big `.data` segment overhead(around 512kb).
# Decode APIs
There're two decode methods:
```c
ssize_t nano_base16_decode_baseline(void * restrict, const char * restrict, size_t);
ssize_t nano_base16_decode(void * restrict, const char * restrict, size_t);
```
The former uses definition-intuitive way for encoding.
The latter decode just like opposite of `nano_base16_encode2`, which take two bytes as a while in each iteration.
# Test
`test.c` provides all possible tests for Base16 encode/decode.
```shell
$ make [ debug | release ]
$ ./test-debug
```
# Benchmark
Benchmark machine:
```
Intel(R) Core(TM) i5-5287U CPU @ 2.90GHz (Max 3.30 GHz, 2 Cores, 4 Threads)
16 GB 1867 MHz DDR3 RAM
```
Without compiler level optimization:
```shell
$ make [ debug ]
$ ./test-debug
Benchmarking size: 1073741824
Time elapsed: 19.2773s nano_base16_encode_baseline()
Time elapsed: 2.45246s nano_base16_encode()
Time elapsed: 1.40033s nano_base16_encode2()
Benchmarking size: 3221225472
Time elapsed: 46.7634s nano_base16_encode_baseline()
Time elapsed: 7.32601s nano_base16_encode()
Time elapsed: 4.20426s nano_base16_encode2()
```
With `-O2` compiler level optimization:
```shell
$ make release
$ ./test
Benchmarking size: 1073741824
Time elapsed: 1.89828s nano_base16_encode_baseline()
Time elapsed: 0.5519s nano_base16_encode()
Time elapsed: 0.332284s nano_base16_encode2()
Benchmarking size: 3221225472
Time elapsed: 5.59842s nano_base16_encode_baseline()
Time elapsed: 1.66608s nano_base16_encode()
Time elapsed: 0.993617s nano_base16_encode2()
```
Above result reveal that the `nano_base16_encode` is a good in-production choice between speed and `.data` segment cache overhead.
`nano_base16_decode_baseline` have similar performance as `nano_base16_encode`.
`nano_base16_decode` have similar performance as `nano_base16_encode2`.
# TODO
* Run tests on big endian machine.
* Windows platform porting.
# *References*
[The Base16, Base32, and Base64 Data Encodings](https://tools.ietf.org/html/rfc4648)
[libbase64 - A simple libbase64 library](https://github.com/gozfree/gear-lib/tree/master/libbase64)
[java base 16 编码和解码](https://gist.github.com/turbidsoul/5226998)