Awesome
Ada_BinToAsc
Introduction
This is an Ada 2012 project that implements various binary-to-ASCII codecs such as Base64. The goal is to create a flexible, well-tested library that fulfils most needs.
The library is licensed under the permissive ISC license without any warranties - see the LICENSE file for details.
Simple usage
The simplest way to use the library is via the RFC4648
package. This
contains various instantiations of generic packages that are intended
to implement the requirements of
RFC4648 for Base16, Base64 etc.
The To_String
functions in each of the instantiations convert a
System.Storage_Elements.Storage_Array
to a string formatted according
to the relevant standard and the To_Bin
function does the reverse.
The To_Bin
function will raise an Invalid_Data_Encoding
exception
if the input is not encoded correctly.
Other uses
If the standard instantiations are not sufficient then the package can
be customised. First the BinToAsc
package has to be instantiated with
suitable parameters for the binary type to be used. The package only
supports 8-bit modular types as the binary type. Then one of the
BinToAsc
child packages can be instantiated with the relevant
alphabet, padding and/or case-sensitivity parameters to give the
required conversion functions.
If encoding or decoding has to be done in a streaming or incremental
fashion then objects of types derived from a root Codec
type have to
be used to maintain the en/decoder state. Every Codec'Class
object
has a State
field that is an enumeration type Ready
, Failed
or
Completed
. The State
should be checked after every conversion to
identify if errors have arisen. A Codec
should not be used again
after it has transitioned to the Failed
or Completed
states unless
it is Reset
.
To do incremental encoding or decoding, call one of the Process
procedures repeatedly with the Codec
, the input data, an output
buffer and a place to store the amount of the output buffer used. The
output buffer used by any call can vary, as the supported encodings all
convert a fixed-size group of binary data into a fixed-size group of
character data or vice-versa. The Input_Group_Size
and
Output_Group_Size
functions of the Codec
object will let you know
how large the output buffer has to be. An extra Output_Group_Size
of
output buffer space is generally required to account for any buffered
data accumulated in the Codec
object from prior operations. To
complete the coding or decoding, call the Complete
procedure which
will potentially output any remaining data received but not converted
by the Codec
, together with any padding required.
Variants supported
There have been many varieties of Base64 and similar codecs used in
products and protocols. The main focus of this project is the variants
suggested by RFC4648. Both Base16
and Base32
can be instantiated in
case-sensitive or case-insensitive variants.
In addition, Base32
also has an option to allow homoglyphs. When
activated, the character '0' in input will be interpreted as 'o' or 'O',
if the supplied alphabet does not already assign a base-32 digit to
'0' but does to 'o' or 'O', and the character '1' will be interpreted
as 'l' or 'I' likewise. This can be useful where Base32 data may be
typed manually from a print-out, as in some typefaces these characters
are so visually similar that they are hard to distinguish.
Some Base64
decoders will ignore junk characters or incorrect padding
etc. Currently this is not supported.
There is also some support for Base85. Currently the only supported variant is the ZeroMQ Z85 specification. A slight extension has been implemented to cope with variable length input. The last few bytes of input that is not a multiple of four bytes in length are padded with zero before being converted to a group of five characters as usual. The number of characters actually output in the last group is reduced by the number of padding bytes added. This maintains compatibility with standard Z85 and is fully reversible.
Build process and tests
Three gprbuild
project files are included. ada_bintoasc.gpr
compiles the library and takes a mode
option that can be debug
,
optimize
or coverage
. The ada_bintoasc_external.gpr
file can be
used instead if you want to prevent recompilation of the library.
The ada_bintoasc_tests.gpr
compiles bintoasc_example
which
demonstrates simple usage of the library and bintoasc_tests
which
runs a series of unit tests. The unit tests have complete coverage of
the library with the exception of the error path in To_String
which
cannot easily be triggered without causing an out-of-memory situation
or other tricks not suitable for unit tests.