Code Monkey home page Code Monkey logo

base64_arduino's Introduction

base64_arduino

Base64 encoder/decoder for arduino repo

npm Build Status

Installation

Add base64.cpp and base64.hpp to your project folder or library search path, put #include "base64.hpp" in your source, and pass base64.cpp to your compiler

Usage (Arduino)

There is an example Arduino sketch in the arduino-test folder.

Usage (libc)

Binary to base64 example:

unsigned char binary[] = {133, 244, 117, 206, 178, 195};
unsigned char base64[9]; // 8 bytes for output + 1 for null terminator

unsigned int base64_length = encode_base64(binary, 6, base64);

printf("%d\n", base64_length); // Prints "8"
printf((char *) base64); // Prints "hfR1zrLD"

Base64 to binary example:

unsigned char base64[] = "hfR1zrLD";
unsigned char binary[6];

unsigned int binary_length = decode_base64(base64, binary);

printf("%d\n", binary_length); // Prints "6"
printf("[%d, %d, %d, %d, %d, %d]\n", // Prints "[133, 244, 117, 206, 178, 195]"
       binary[0], binary[1], binary[2],
       binary[3], binary[4], binary[5]);

String to base64 example:

unsigned char string[] = "String example";
unsigned char base64[21]; // 20 bytes for output + 1 for null terminator

// encode_base64() places a null terminator automatically, because the output is a string
unsigned int base64_length = encode_base64(string, strlen((char *) string), base64);

printf("%d\n", base64_length); // Prints "20"
printf((char *) base64); // Prints "U3RyaW5nIGV4YW1wbGU="

Base64 to string example:

unsigned char base64[] = "U3RyaW5nIGV4YW1wbGU=";
unsigned char string[15]; // 14 bytes for output + 1 for null terminator

// decode_base64() does not place a null terminator, because the output is not always a string
unsigned int string_length = decode_base64(base64, string);
string[string_length] = '\0';

printf("%d\n", string_length); // Prints "14"
printf((char *) string); // Prints "String example"

Details

By default, uses common web conventions - '+' for 62, '/' for 63, '=' for padding. Optionally, define the BASE64_URL macro to follow RFC 4648 §5 for filesystem/URL safe output ('-' for 62 and '_' for 63). Note that invalid base64 characters are interpreted as padding.

Can be compiled as C, uses .*pp extensions because it is usually used in C++ projects and is tested for C++.

License

MIT

base64_arduino's People

Contributors

danielbuechele avatar densaugeo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

base64_arduino's Issues

very very small issue on declaration

Hi..
I'm using your code.
So, thank you very much. :)

When I read your code, I found a small misprint.
The parameter name should be changed 'v' to 'c' on src/base64.hpp line 27.

Have a nice day~

input args should be const to use them with String::c_str()

Hi, I like your code because it is small and simple.
I think it could be slightly improved by making the input args const so they can be used directly by passing the result of String::c_str().

I tried to add a branch and add a pull request, but I do not have permissions. Instead, I send you the code in this text.

Best regards, TinkerPHU

/**
 * Base64 encoding and decoding of strings. Uses '+' for 62, '/' for 63, '=' for padding
 */

#pragma once

/* binary_to_base64:
 *   Description:
 *     Converts a single byte from a binary value to the corresponding base64 character
 *   Parameters:
 *     v - Byte to convert
 *   Returns:
 *     ascii code of base64 character. If byte is >= 64, then there is not corresponding base64 character
 *     and 255 is returned
 */
unsigned char binary_to_base64(unsigned char v);

/* base64_to_binary:
 *   Description:
 *     Converts a single byte from a base64 character to the corresponding binary value
 *   Parameters:
 *     c - Base64 character (as ascii code)
 *   Returns:
 *     6-bit binary value
 */
unsigned char base64_to_binary(unsigned char c);

/* encode_base64_length:
 *   Description:
 *     Calculates length of base64 string needed for a given number of binary bytes
 *   Parameters:
 *     input_length - Amount of binary data in bytes
 *   Returns:
 *     Number of base64 characters needed to encode input_length bytes of binary data
 */
unsigned int encode_base64_length(unsigned int input_length);

/* decode_base64_length:
 *   Description:
 *     Calculates number of bytes of binary data in a base64 string
 *     Variant that does not use input_length no longer used within library, retained for API compatibility
 *   Parameters:
 *     input - Base64-encoded null-terminated string
 *     input_length (optional) - Number of bytes to read from input pointer
 *   Returns:
 *     Number of bytes of binary data in input
 */
unsigned int decode_base64_length(const unsigned char input[]);
unsigned int decode_base64_length(const unsigned char input[], unsigned int input_length);

/* encode_base64:
 *   Description:
 *     Converts an array of bytes to a base64 null-terminated string
 *   Parameters:
 *     input - Pointer to input data
 *     input_length - Number of bytes to read from input pointer
 *     output - Pointer to output string. Null terminator will be added automatically
 *   Returns:
 *     Length of encoded string in bytes (not including null terminator)
 */
unsigned int encode_base64(const unsigned char input[], unsigned int input_length, unsigned char output[]);

/* decode_base64:
 *   Description:
 *     Converts a base64 null-terminated string to an array of bytes
 *   Parameters:
 *     input - Pointer to input string
 *     input_length (optional) - Number of bytes to read from input pointer
 *     output - Pointer to output array
 *   Returns:
 *     Number of bytes in the decoded binary
 */
unsigned int decode_base64(const unsigned char input[], unsigned char output[]);
unsigned int decode_base64(const unsigned char input[], unsigned int input_length, unsigned char output[]);

unsigned char binary_to_base64(unsigned char v) {
  // Capital letters - 'A' is ascii 65 and base64 0
  if(v < 26) return v + 'A';
  
  // Lowercase letters - 'a' is ascii 97 and base64 26
  if(v < 52) return v + 71;
  
  // Digits - '0' is ascii 48 and base64 52
  if(v < 62) return v - 4;
  
  // '+' is ascii 43 and base64 62
  if(v == 62) return '+';
  
  // '/' is ascii 47 and base64 63
  if(v == 63) return '/';
  
  return 64;
}

unsigned char base64_to_binary(unsigned char c) {
  // Capital letters - 'A' is ascii 65 and base64 0
  if('A' <= c && c <= 'Z') return c - 'A';
  
  // Lowercase letters - 'a' is ascii 97 and base64 26
  if('a' <= c && c <= 'z') return c - 71;
  
  // Digits - '0' is ascii 48 and base64 52
  if('0' <= c && c <= '9') return c + 4;
  
  // '+' is ascii 43 and base64 62
  if(c == '+') return 62;
  
  // '/' is ascii 47 and base64 63
  if(c == '/') return 63;
  
  return 255;
}

unsigned int encode_base64_length(unsigned int input_length) {
  return (input_length + 2)/3*4;
}

unsigned int decode_base64_length(const unsigned char input[]) {
  return decode_base64_length(input, -1);
}

unsigned int decode_base64_length(const unsigned char input[], unsigned int input_length) {
  const unsigned char *start = input;
  
  while(base64_to_binary(input[0]) < 64 && (unsigned int) (input - start) < input_length) {
    ++input;
  }
  
  input_length = (unsigned int) (input - start);
  return input_length/4*3 + (input_length % 4 ? input_length % 4 - 1 : 0);
}

unsigned int encode_base64(const char* input, unsigned int input_length, unsigned char output[]) {
    return encode_base64(reinterpret_cast<const unsigned char*>(input),input_length,output);
}

unsigned int encode_base64(const unsigned char input[], unsigned int input_length, unsigned char output[]) {
  unsigned int full_sets = input_length/3;
  
  // While there are still full sets of 24 bits...
  for(unsigned int i = 0; i < full_sets; ++i) {
    output[0] = binary_to_base64(                         input[0] >> 2);
    output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
    output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6);
    output[3] = binary_to_base64( input[2] & 0x3F);
    
    input += 3;
    output += 4;
  }
  
  switch(input_length % 3) {
    case 0:
      output[0] = '\0';
      break;
    case 1:
      output[0] = binary_to_base64(                         input[0] >> 2);
      output[1] = binary_to_base64((input[0] & 0x03) << 4);
      output[2] = '=';
      output[3] = '=';
      output[4] = '\0';
      break;
    case 2:
      output[0] = binary_to_base64(                         input[0] >> 2);
      output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
      output[2] = binary_to_base64((input[1] & 0x0F) << 2);
      output[3] = '=';
      output[4] = '\0';
      break;
  }
  
  return encode_base64_length(input_length);
}

unsigned int decode_base64(const unsigned char input[], unsigned char output[]) {
  return decode_base64(input, -1, output);
}

unsigned int decode_base64(const unsigned char input[], unsigned int input_length, unsigned char output[]) {
  unsigned int output_length = decode_base64_length(input, input_length);
  
  // While there are still full sets of 24 bits...
  for(unsigned int i = 2; i < output_length; i += 3) {
    output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
    output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
    output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]);
    
    input += 4;
    output += 3;
  }
  
  switch(output_length % 3) {
    case 1:
      output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
      break;
    case 2:
      output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
      output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
      break;
  }
  
  return output_length;
}



Excuse me

Sir,i cant see the "base64.cpp".Could u tell me where i should to get this code.

Compatibility w.r.t iMX RT1064 in MCUXpresso IDE

Hi @Densaugeo @danielbuechele ,
I'm using MicroOCPP_Simulator and I'm trying to port to iMX RT1064 MCU as @matth-x told that it is possible.

During the course, I got stuck in the following error, which is attached as log. Kindly do look into it and let me know where it went wrong.

I'm suspecting that the precompiled code - base64.hpp - does it work for toolchain of iMX RT1064? I'm just guessing. Let me know @danielbuechele @Densaugeo

PS : Also @matth-x kindly do what help can be done .. 👍
Uploading ArduinoJSON.log…

Compiler complains about comparison between signed and unsigned ints

When I compile a project with this library installed, the compiler complains about line 126 in base64.hpp, specifically about

input - start < input_length

input is always equal or larger than start, so that should never be an issue, but the compiler would like it better if it was changed to

(unsigned int) (input - start) < input_length

I guess.

Potential buffer overflow with decode_base64

It looks like decode_base64 doesn't look at the allocated space of the output. It could be an improvement to add a third parameter to specify the maximum output size, similarly to encode_base64.

how to set a dynamic string?

Hi,
i get a dynamic string. i can't figure it out,
what is the modifications that i should do?

A tiny example will be very helpful

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.