Skip to content

artemkin/z85

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Z85

Build Status Coverage Status

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++.

Install

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.

Usage

Hello World

#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.

Hello World 2

#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!