Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZARMOUR(3)			   CZMQ Manual			      ZARMOUR(3)

NAME
     zarmour - Class for armoured text encoding and decoding

SYNOPSIS
     //  This is a stable class, and may not change except for emergencies. It
     //  is provided in stable builds.
     #define ZARMOUR_MODE_BASE64_STD 0		  // Standard base 64
     #define ZARMOUR_MODE_BASE64_URL 1		  // URL and filename friendly base 64
     #define ZARMOUR_MODE_BASE32_STD 2		  // Standard base 32
     #define ZARMOUR_MODE_BASE32_HEX 3		  // Extended hex base 32
     #define ZARMOUR_MODE_BASE16 4		  // Standard base 16
     #define ZARMOUR_MODE_Z85 5 		  // Z85 from ZeroMQ RFC 32

     //  Create a new zarmour
     CZMQ_EXPORT zarmour_t *
	 zarmour_new (void);

     //  Destroy the zarmour
     CZMQ_EXPORT void
	 zarmour_destroy (zarmour_t **self_p);

     //  Encode a stream of bytes into an armoured string. Returns the armoured
     //  string, or NULL if there was insufficient memory available to allocate
     //  a new string.
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT char *
	 zarmour_encode (zarmour_t *self, const byte *data, size_t size);

     //  Decode an armoured string into a chunk. The decoded output is
     //  null-terminated, so it may be treated as a string, if that's what
     //  it was prior to encoding.
     //  Caller owns return value and must destroy it when done.
     CZMQ_EXPORT zchunk_t *
	 zarmour_decode (zarmour_t *self, const char *data);

     //  Get the mode property.
     CZMQ_EXPORT int
	 zarmour_mode (zarmour_t *self);

     //  Get printable string for mode.
     CZMQ_EXPORT const char *
	 zarmour_mode_str (zarmour_t *self);

     //  Set the mode property.
     CZMQ_EXPORT void
	 zarmour_set_mode (zarmour_t *self, int mode);

     //  Return true if padding is turned on.
     CZMQ_EXPORT bool
	 zarmour_pad (zarmour_t *self);

     //  Turn padding on or off. Default is on.
     CZMQ_EXPORT void
	 zarmour_set_pad (zarmour_t *self, bool pad);

     //  Get the padding character.
     CZMQ_EXPORT char
	 zarmour_pad_char (zarmour_t *self);

     //  Set the padding character.
     CZMQ_EXPORT void
	 zarmour_set_pad_char (zarmour_t *self, char pad_char);

     //  Return if splitting output into lines is turned on. Default is off.
     CZMQ_EXPORT bool
	 zarmour_line_breaks (zarmour_t *self);

     //  Turn splitting output into lines on or off.
     CZMQ_EXPORT void
	 zarmour_set_line_breaks (zarmour_t *self, bool line_breaks);

     //  Get the line length used for splitting lines.
     CZMQ_EXPORT size_t
	 zarmour_line_length (zarmour_t *self);

     //  Set the line length used for splitting lines.
     CZMQ_EXPORT void
	 zarmour_set_line_length (zarmour_t *self, size_t line_length);

     //  Print properties of object
     CZMQ_EXPORT void
	 zarmour_print (zarmour_t *self);

     //  Self test of this class.
     CZMQ_EXPORT void
	 zarmour_test (bool verbose);

     Please add '@interface' section in './../src/zarmour.c'.

DESCRIPTION
     zarmour - armoured text encoding and decoding

     The  zarmour  class implements encoding and decoding of armoured text data.
     The    following	  codecs     are     implemented:     *     RFC     4648
     (http://www.ietf.org/rfc/rfc4648.txt)  -  base64  -  base64url  -	base32 -
     base32hex - base16 * Z85 (http://rfc.zeromq.org/spec:32) All RFC4648 base64
     and base32 variants support padding the output. The pad character	is  con-
     figurable.  Default  is padding on, with character =. Additionally, in some
     cases (e.g. MIME), splitting the output into lines of a specific length  is
     required. This feature is also supported, though turned off by default. The
     z85  mode	does neither padding nor line breaks; it is merely a wrapping of
     the corresponding libzmq methods. Encoding will assert if input  length  is
     not  divisible by 4 and decoding will assert if input length is not divisi-
     ble by 5.

EXAMPLE
     From zarmour_test method.

	 zarmour_t *self = zarmour_new ();
	 assert (self);

	 int mode = zarmour_mode (self);
	 assert (mode == ZARMOUR_MODE_BASE64_STD);

	 zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
	 mode = zarmour_mode (self);
	 assert (mode == ZARMOUR_MODE_BASE64_URL);

	 assert (zarmour_pad (self));
	 zarmour_set_pad (self, false);
	 assert (!zarmour_pad (self));

	 assert (zarmour_pad_char (self) == '=');
	 zarmour_set_pad_char (self, '!');
	 assert (zarmour_pad_char (self) == '!');
	 zarmour_set_pad_char (self, '=');
	 assert (zarmour_pad_char (self) == '=');

	 assert (!zarmour_line_breaks (self));
	 zarmour_set_line_breaks (self, true);
	 assert (zarmour_line_breaks (self));

	 assert (zarmour_line_length (self) == 72);
	 zarmour_set_line_length (self, 64);
	 assert (zarmour_line_length (self) == 64);

	 //  Test against test vectors from RFC4648.
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "Zg", verbose);
	 s_armour_test (self, "fo", "Zm8", verbose);
	 s_armour_test (self, "foo", "Zm9v", verbose);
	 s_armour_test (self, "foob", "Zm9vYg", verbose);
	 s_armour_test (self, "fooba", "Zm9vYmE", verbose);
	 s_armour_test (self, "foobar", "Zm9vYmFy", verbose);
	 zarmour_set_pad (self, true);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "Zg==", verbose);
	 s_armour_test (self, "fo", "Zm8=", verbose);
	 s_armour_test (self, "foo", "Zm9v", verbose);
	 s_armour_test (self, "foob", "Zm9vYg==", verbose);
	 s_armour_test (self, "fooba", "Zm9vYmE=", verbose);
	 s_armour_test (self, "foobar", "Zm9vYmFy", verbose);

	 zarmour_set_pad (self, false);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "Zg", verbose);
	 s_armour_test (self, "fo", "Zm8", verbose);
	 s_armour_test (self, "foo", "Zm9v", verbose);
	 s_armour_test (self, "foob", "Zm9vYg", verbose);
	 s_armour_test (self, "fooba", "Zm9vYmE", verbose);
	 s_armour_test (self, "foobar", "Zm9vYmFy", verbose);
	 zarmour_set_pad (self, true);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "Zg==", verbose);
	 s_armour_test (self, "fo", "Zm8=", verbose);
	 s_armour_test (self, "foo", "Zm9v", verbose);
	 s_armour_test (self, "foob", "Zm9vYg==", verbose);
	 s_armour_test (self, "fooba", "Zm9vYmE=", verbose);
	 s_armour_test (self, "foobar", "Zm9vYmFy", verbose);

	 zarmour_set_pad (self, false);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "MY", verbose);
	 s_armour_test (self, "fo", "MZXQ", verbose);
	 s_armour_test (self, "foo", "MZXW6", verbose);
	 s_armour_test (self, "foob", "MZXW6YQ", verbose);
	 s_armour_test (self, "fooba", "MZXW6YTB", verbose);
	 s_armour_test (self, "foobar", "MZXW6YTBOI", verbose);
	 s_armour_decode (self, "my", "f", verbose);
	 s_armour_decode (self, "mzxq", "fo", verbose);
	 s_armour_decode (self, "mzxw6", "foo", verbose);
	 s_armour_decode (self, "mzxw6yq", "foob", verbose);
	 s_armour_decode (self, "mzxw6ytb", "fooba", verbose);
	 s_armour_decode (self, "mzxw6ytboi", "foobar", verbose);
	 zarmour_set_pad (self, true);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "MY======", verbose);
	 s_armour_test (self, "fo", "MZXQ====", verbose);
	 s_armour_test (self, "foo", "MZXW6===", verbose);
	 s_armour_test (self, "foob", "MZXW6YQ=", verbose);
	 s_armour_test (self, "fooba", "MZXW6YTB", verbose);
	 s_armour_test (self, "foobar", "MZXW6YTBOI======", verbose);
	 s_armour_decode (self, "my======", "f", verbose);
	 s_armour_decode (self, "mzxq====", "fo", verbose);
	 s_armour_decode (self, "mzxw6===", "foo", verbose);
	 s_armour_decode (self, "mzxw6yq=", "foob", verbose);
	 s_armour_decode (self, "mzxw6ytb", "fooba", verbose);
	 s_armour_decode (self, "mzxw6ytboi======", "foobar", verbose);

	 zarmour_set_pad (self, false);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "CO", verbose);
	 s_armour_test (self, "fo", "CPNG", verbose);
	 s_armour_test (self, "foo", "CPNMU", verbose);
	 s_armour_test (self, "foob", "CPNMUOG", verbose);
	 s_armour_test (self, "fooba", "CPNMUOJ1", verbose);
	 s_armour_test (self, "foobar", "CPNMUOJ1E8", verbose);
	 s_armour_decode (self, "co", "f", verbose);
	 s_armour_decode (self, "cpng", "fo", verbose);
	 s_armour_decode (self, "cpnmu", "foo", verbose);
	 s_armour_decode (self, "cpnmuog", "foob", verbose);
	 s_armour_decode (self, "cpnmuoj1", "fooba", verbose);
	 s_armour_decode (self, "cpnmuoj1e8", "foobar", verbose);
	 zarmour_set_pad (self, true);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "CO======", verbose);
	 s_armour_test (self, "fo", "CPNG====", verbose);
	 s_armour_test (self, "foo", "CPNMU===", verbose);
	 s_armour_test (self, "foob", "CPNMUOG=", verbose);
	 s_armour_test (self, "fooba", "CPNMUOJ1", verbose);
	 s_armour_test (self, "foobar", "CPNMUOJ1E8======", verbose);
	 s_armour_decode (self, "co======", "f", verbose);
	 s_armour_decode (self, "cpng====", "fo", verbose);
	 s_armour_decode (self, "cpnmu===", "foo", verbose);
	 s_armour_decode (self, "cpnmuog=", "foob", verbose);
	 s_armour_decode (self, "cpnmuoj1", "fooba", verbose);
	 s_armour_decode (self, "cpnmuoj1e8======", "foobar", verbose);
	 zarmour_set_pad (self, true);

	 zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "f", "66", verbose);
	 s_armour_test (self, "fo", "666F", verbose);
	 s_armour_test (self, "foo", "666F6F", verbose);
	 s_armour_test (self, "foob", "666F6F62", verbose);
	 s_armour_test (self, "fooba", "666F6F6261", verbose);
	 s_armour_test (self, "foobar", "666F6F626172", verbose);
	 s_armour_decode (self, "666f", "fo", verbose);
	 s_armour_decode (self, "666f6f", "foo", verbose);
	 s_armour_decode (self, "666f6f62", "foob", verbose);
	 s_armour_decode (self, "666f6f6261", "fooba", verbose);
	 s_armour_decode (self, "666f6f626172", "foobar", verbose);

	 #ifdef _INCLUDE_Z85
	 //  Z85 test is homemade; using 0, 4 and 8 bytes, with precalculated
	 //  test vectors created with a libzmq test.
	 //  ----------------------------------------------------------------

	 //  Make a fake curve key from hex (base16) string, making sure
	 //  there are no null bytes inside, so we can use our test utility
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
	 zarmour_set_line_breaks (self, false);

	 zchunk_t *chunk = zarmour_decode (self,
	     "4E6F87E2FB6EB22A1EF5E257B75D79124949565F0B8B36A878A4F03111C96E0B");
	 assert (chunk);

	 zarmour_set_mode (self, ZARMOUR_MODE_Z85);  //  Z85 mode does not support padding or line breaks
	 zarmour_set_pad (self, false); 	     //  so these two are superfluous;
	 zarmour_set_line_breaks (self, false);      //  just for consistency
	 if (verbose)
	     zarmour_print (self);

	 s_armour_test (self, "", "", verbose);
	 s_armour_test (self, "foob", "w]zP%", verbose);
	 s_armour_test (self, "foobar!!", "w]zP%vr9Im", verbose);
	 s_armour_test (self, (char *) zchunk_data (chunk),
			"ph+{E}!&X?9}!I]W{sm(nL8@&3Yu{wC+<*-5Y[[#", verbose);
	 zchunk_destroy (&chunk);
	 #endif

	 //  Armouring longer byte array to test line breaks
	 zarmour_set_pad (self, true);
	 zarmour_set_line_breaks (self, true);
	 byte test_data [256];
	 int index;
	 for (index = 0; index < 256; index++)
	     test_data [index] = index;

	 zarmour_set_mode (self, ZARMOUR_MODE_BASE64_STD);
	 s_armour_test_long (self, test_data, 256, verbose);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE64_URL);
	 s_armour_test_long (self, test_data, 256, verbose);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE32_STD);
	 s_armour_test_long (self, test_data, 256, verbose);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE32_HEX);
	 s_armour_test_long (self, test_data, 256, verbose);
	 zarmour_set_mode (self, ZARMOUR_MODE_BASE16);
	 s_armour_test_long (self, test_data, 256, verbose);
	 #ifdef _INCLUDE_Z85
	 zarmour_set_mode (self, ZARMOUR_MODE_Z85);
	 s_armour_test_long (self, test_data, 256, verbose);
	 #endif

	 zarmour_destroy (&self);

	 #if defined (__WINDOWS__)
	 zsys_shutdown();
	 #endif

AUTHORS
     The czmq manual was written by the authors in the AUTHORS file.

RESOURCES
     Main web site:

     Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
     Copyright (c) the Contributors as noted in the AUTHORS file. This	file  is
     part  of  CZMQ,  the  high-level C binding for 0MQ: http://czmq.zeromq.org.
     This Source Code Form is subject to the terms of  the  Mozilla  Public  Li-
     cense, v. 2.0. If a copy of the MPL was not distributed with this file, You
     can  obtain  one  at http://mozilla.org/MPL/2.0/. LICENSE included with the
     czmq distribution.

NOTES
      1. zeromq-dev@lists.zeromq.org
	 mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.2.1			   08/27/2026			      ZARMOUR(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zarmour&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help