GithubHelp home page GithubHelp logo

jqk6 / base64 Goto Github PK

View Code? Open in Web Editor NEW

This project forked from inkymail/base64

0.0 0.0 0.0 135 KB

Base64 stream encoder/decoder in C89, with SSE acceleration

License: BSD 2-Clause "Simplified" License

Makefile 1.79% C 98.21%

base64's Introduction

About this fork

This is Inkymail's fork of aklomp's base64 library. This fork adds support for AVX2 and ARM NEON istructions. It also auto-detecets SSSE3 and AVX2 instructions at runtime and chooses the best codec accordingly, which prevents illegal instruction traps on older CPUs that don't support these instructions.

Also added in this fork is support for URL-safe base64 and optional ignoring of illegal characters in the base64 stream (rather than aborting when an illegal character is encountered.)

The remainder of this readme is identical to what's in the upstream repository.

Base64 stream encoder/decoder in C89

This is an implementation of a base64 stream encoder/decoder in C89. It also contains wrapper functions to encode/decode simple length-delimited strings.

If your processor supports SSSE3, encoding/decoding speed is about four times higher than the competition, because this library uses SSE intrinsics to encode/decode twelve bytes at a time. To the author's knowledge, this is the only Base64 library that does this.

Notable features:

  • Really fast on x86 systems by using SSE vector instructions;
  • Reads/writes blocks of streaming data;
  • Does not dynamically allocate memory;
  • Valid C89 that compiles with pedantic options on;
  • Re-entrant and threadsafe;
  • Unit tested;
  • Uses Duff's Device.

Strings are represented as a pointer and a length; they are not zero-terminated. This was a conscious design decision. In the decoding step, relying on zero-termination would make no sense since the output could contain legitimate zero bytes. In the encoding step, returning the length saves the overhead of calling strlen() on the output. If you insist on the trailing zero, you can easily add it yourself at the given offset.

Usage and building

To use the library routines, include base64.c and base64.h into your project. No special compiler flags are necessary to build the files. If your target supports it, compile with -mssse3 or equivalent to benefit from SSSE3 acceleration.

API reference

Encoding

base64_encode

void base64_encode (const char *const src, size_t srclen, char *const out, size_t *const outlen);

Wrapper function to encode a plain string of given length. Output is written to out without trailing zero. Output length in bytes is written to outlen. The buffer in out has been allocated by the caller and is at least 4/3 the size of the input.

base64_stream_encode_init

void base64_stream_encode_init (struct base64_state *);

Call this before calling base64_stream_encode() to init the state.

base64_stream_encode

void base64_stream_encode (struct base64_state *, const char *const src, size_t srclen, char *const out, size_t *const outlen);

Encodes the block of data of given length at src, into the buffer at out. Caller is responsible for allocating a large enough out-buffer; it must be at least 4/3 the size of the in-buffer, but take some margin. Places the number of new bytes written into outlen (which is set to zero when the function starts). Does not zero-terminate or finalize the output.

base64_stream_encode_final

void base64_stream_encode_final (struct base64_state *, char *const out, size_t *outlen);

Finalizes the output begun by previous calls to base64_stream_encode(). Adds the required end-of-stream markers if appropriate. outlen is modified and will contain the number of new bytes written at out (which will quite often be zero).

Decoding

base64_decode

int base64_decode (const char *const src, size_t srclen, char *const out, size_t *const outlen);

Wrapper function to decode a plain string of given length. Output is written to out without trailing zero. Output length in bytes is written to outlen. The buffer in out has been allocated by the caller and is at least 3/4 the size of the input.

base64_stream_decode_init

void base64_stream_decode_init (struct base64_state *);

Call this before calling base64_stream_decode() to init the state.

base64_stream_decode

int base64_stream_decode (struct base64_state *, const char *const src, size_t srclen, char *const out, size_t *const outlen);

Decodes the block of data of given length at src, into the buffer at out. Caller is responsible for allocating a large enough out-buffer; it must be at least 3/4 the size of the in-buffer, but take some margin. Places the number of new bytes written into outlen (which is set to zero when the function starts). Does not zero-terminate the output. Returns 1 if all is well, and 0 if a decoding error was found, such as an invalid character.

Examples

A simple example of encoding a static string to base64 and printing the output to stdout:

#include <stdio.h>	/* fwrite */
#include "base64.h"

int main ()
{
	char src[] = "hello world";
	char out[20];
	size_t srclen = sizeof(src) - 1;
	size_t outlen;

	base64_encode(src, srclen, out, &outlen);

	fwrite(out, outlen, 1, stdout);

	return 0;
}

A simple example (no error checking, etc) of stream encoding standard input to standard output:

#include <stdio.h>
#include "base64.h"

int main ()
{
	size_t nread, nout;
	char buf[12000], out[16000];
	struct base64_state state;

	base64_stream_encode_init(&state);
	while ((nread = fread(buf, 1, sizeof(buf), stdin)) > 0) {
		base64_stream_encode(&state, buf, nread, out, &nout);
		if (nout) fwrite(out, nout, 1, stdout);
		if (feof(stdin)) break;
	}
	base64_stream_encode_final(&state, out, &nout);
	if (nout) fwrite(out, nout, 1, stdout);

	return 0;
}

Also see main.c for a simple re-implementation of the base64 utility. A file or standard input is fed through the encoder/decoder, and the output is written to standard output.

Tests

See tests/ for a small test suite. Testing is automated with Travis CI:

Build Status

License

This repository is licensed under the BSD 2-clause License. See the LICENSE file.

base64's People

Contributors

aklomp avatar dmbaggett avatar sgs1370 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.