123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /**
- * Base64 encoder/decoder for arduino repo
- * Uses common web conventions - '+' for 62, '/' for 63, '=' for padding.
- * Note that invalid base64 characters are interpreted as padding.
- * Author: Densaugeo
- * Maintainer: Densaugeo
- * Version: 1.2.1.1
- * Changed unsigned int to uint16_t for use in the professional Ender 3V2/S1 firmware
- * Url: https://www.arduino.cc/reference/en/libraries/base64/
- */
-
- #ifndef BASE64_H_INCLUDED
- #define BASE64_H_INCLUDED
-
- /* 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
- */
- uint16_t encode_base64_length(uint16_t 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
- */
- uint16_t decode_base64_length(unsigned char input[]);
- uint16_t decode_base64_length(unsigned char input[], uint16_t 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)
- */
- uint16_t encode_base64(unsigned char input[], uint16_t 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
- */
- uint16_t decode_base64(unsigned char input[], unsigned char output[]);
- uint16_t decode_base64(unsigned char input[], uint16_t 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;
- }
-
- uint16_t encode_base64_length(uint16_t input_length) {
- return (input_length + 2)/3*4;
- }
-
- uint16_t decode_base64_length(unsigned char input[]) {
- return decode_base64_length(input, -1);
- }
-
- uint16_t decode_base64_length(unsigned char input[], uint16_t input_length) {
- unsigned char *start = input;
-
- while (base64_to_binary(input[0]) < 64 && (unsigned char)(input - start) < input_length) {
- ++input;
- }
-
- input_length = input - start;
- return input_length/4*3 + (input_length % 4 ? input_length % 4 - 1 : 0);
- }
-
- uint16_t encode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) {
- uint16_t full_sets = input_length/3;
-
- // While there are still full sets of 24 bits...
- for (uint16_t 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);
- }
-
- uint16_t decode_base64(unsigned char input[], unsigned char output[]) {
- return decode_base64(input, -1, output);
- }
-
- uint16_t decode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) {
- uint16_t output_length = decode_base64_length(input, input_length);
-
- // While there are still full sets of 24 bits...
- for (uint16_t 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;
- }
-
- #endif // BASE64_H_INCLUDED
|