Z85 is a binary-to-text encoding library. It implements ZeroMQ Base-85 Encoding Algorithm and provides custom padding. Z85 is written in C and C++.
Just grab z85.h
and z85.c
to your project, compile and link.
Don't forget to take z85.hpp
and z85_impl.cpp
if you need C++ interface.
#include "stdio.h"
#include "string.h"
#include "z85/z85.h"
int main()
{
char helloData[8] = "\x86\x4F\xD2\x6F\xB5\x59\xF7\x5B";
// Encode binary to printable string
char encBuf[10+1] = {}; // +1 for null terminating char
size_t bytesEncoded = Z85_encode(helloData, encBuf, 8);
// Decode printable string to binary
char decBuf[8] = {};
size_t bytesDecoded = Z85_decode(encBuf, decBuf, bytesEncoded);
printf("%s", encBuf);
if (bytesEncoded == 10 &&
bytesDecoded == 8 &&
!memcmp(helloData, decBuf, 8))
{
printf("!\n");
}
return 0;
}
Output
HelloWorld!
8 bytes of helloData
are encoded into "HelloWorld" (10 ASCII symbols). The overhead of encoding is 25%.
Z85_encode
and Z85_decode
are implemented according to
Z85 specification.
So, Z85_encode
expects as input a binary string that length is divisible by 4 with no remainder, and
Z85_decode
expects as input a printable string that length is divisible by 5 with no remainder.
It may be inconvenient, so the library provides functions that pad input strings to meet the above-mentioned requirements:
Z85_encode_with_padding
and Z85_decode_with_padding
.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "z85/z85.h"
char* encode(const char* src, size_t len)
{
// allocate output buffer (+1 for null terminating char)
char* dest = (char*)malloc(Z85_encode_with_padding_bound(len) + 1);
if (len == 0)
{
dest[0] = '\0'; // write null terminating char
return dest;
}
// encode the input buffer, padding it if necessary
len = Z85_encode_with_padding(src, dest, len);
if (len == 0) // something went wrong
{
free(dest);
return NULL;
}
dest[len] = '\0'; // write null terminating char
return dest;
}
int main()
{
char* str = encode("\x86\x4F\xD2\x6F\xB5\x59\xF7\x5B", 8);
if (str)
{
printf("%s\n", str);
free(str);
}
return 0;
}
Output
4HelloWorld
Z85_encode_with_padding_bound
is used to evaluate the size of output buffer.
This function returns exact size of the output buffer, so you do not need to shrink it after encoding.
The first symbol in encoded string ('4' in our example) stores a number of significant bytes contained in the remainder of input data.
Original Z85 algorithm can't encode byte sequence that length is not divisible by 4 with no remainder. In Z85_encode_with_padding
we pad the input remainder with '\0' bytes, encode the whole input with original algorithm and save a number of significat bytes
in the reminder. '4' means no padding was even applied. '1', '2', '3' and '4' are possible values.
See z85.h
for more details. It is well commented, so you can figure out
how to decode padded string by yourself.
Good luck!