nostril

A C cli tool for creating nostr events
git clone git://jb55.com/nostril
Log | Files | Refs | Submodules | README | LICENSE

base64.h (8552B)


      1 /* Licensed under BSD-MIT - see LICENSE file for details */
      2 #ifndef CCAN_BASE64_H
      3 #define CCAN_BASE64_H
      4 
      5 #include <stddef.h>
      6 #include <stdbool.h>
      7 #include <sys/types.h>
      8 
      9 /**
     10  * base64_maps_t - structure to hold maps for encode/decode
     11  */
     12 typedef struct {
     13 	char encode_map[64];
     14 	signed char decode_map[256];
     15 } base64_maps_t;
     16 
     17 /**
     18  * base64_encoded_length - Calculate encode buffer length
     19  * @param srclen the size of the data to be encoded
     20  * @note add 1 to this to get null-termination
     21  * @return Buffer length required for encode
     22  */
     23 size_t base64_encoded_length(size_t srclen);
     24 
     25 /**
     26  * base64_decoded_length - Calculate decode buffer length
     27  * @param srclen Length of the data to be decoded
     28  * @note This does not return the size of the decoded data!  see base64_decode
     29  * @return Minimum buffer length for safe decode
     30  */
     31 size_t base64_decoded_length(size_t srclen);
     32 
     33 /**
     34  * base64_init_maps - populate a base64_maps_t based on a supplied alphabet
     35  * @param dest A base64 maps object
     36  * @param src Alphabet to populate the maps from (e.g. base64_alphabet_rfc4648)
     37  */
     38 void base64_init_maps(base64_maps_t *dest, const char src[64]);
     39 
     40 
     41 /**
     42  * base64_encode_triplet_using_maps - encode 3 bytes into base64 using a specific alphabet
     43  * @param maps Maps to use for encoding (see base64_init_maps)
     44  * @param dest Buffer containing 3 bytes
     45  * @param src Buffer containing 4 characters
     46  */
     47 void base64_encode_triplet_using_maps(const base64_maps_t *maps,
     48 				      char dest[4], const char src[3]);
     49 
     50 /**
     51  * base64_encode_tail_using_maps - encode the final bytes of a source using a specific alphabet
     52  * @param maps Maps to use for encoding (see base64_init_maps)
     53  * @param dest Buffer containing 4 bytes
     54  * @param src Buffer containing srclen bytes
     55  * @param srclen Number of bytes (<= 3) to encode in src
     56  */
     57 void base64_encode_tail_using_maps(const base64_maps_t *maps, char dest[4],
     58 				   const char *src, size_t srclen);
     59 
     60 /**
     61  * base64_encode_using_maps - encode a buffer into base64 using a specific alphabet
     62  * @param maps Maps to use for encoding (see base64_init_maps)
     63  * @param dest Buffer to encode into
     64  * @param destlen Length of dest
     65  * @param src Buffer to encode
     66  * @param srclen Length of the data to encode
     67  * @return Number of encoded bytes set in dest. -1 on error (and errno set)
     68  * @note dest will be nul-padded to destlen (past any required padding)
     69  * @note sets errno = EOVERFLOW if destlen is too small
     70  */
     71 ssize_t base64_encode_using_maps(const base64_maps_t *maps,
     72 				 char *dest, size_t destlen,
     73 				 const char *src, size_t srclen);
     74 
     75 /*
     76  * base64_char_in_alphabet - returns true if character can be part of an encoded string
     77  * @param maps A base64 maps object (see base64_init_maps)
     78  * @param b64char Character to check
     79  */
     80 bool base64_char_in_alphabet(const base64_maps_t *maps, char b64char);
     81 
     82 /**
     83  * base64_decode_using_maps - decode a base64-encoded string using a specific alphabet
     84  * @param maps A base64 maps object (see base64_init_maps)
     85  * @param dest Buffer to decode into
     86  * @param destlen length of dest
     87  * @param src the buffer to decode
     88  * @param srclen the length of the data to decode
     89  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
     90  * @note dest will be nul-padded to destlen
     91  * @note sets errno = EOVERFLOW if destlen is too small
     92  * @note sets errno = EDOM if src contains invalid characters
     93  */
     94 ssize_t base64_decode_using_maps(const base64_maps_t *maps,
     95 				 char *dest, size_t destlen,
     96 				 const char *src, size_t srclen);
     97 
     98 /**
     99  * base64_decode_quartet_using_maps - decode 4 bytes from base64 using a specific alphabet
    100  * @param maps A base64 maps object (see base64_init_maps)
    101  * @param dest Buffer containing 3 bytes
    102  * @param src Buffer containing 4 bytes
    103  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
    104  * @note sets errno = EDOM if src contains invalid characters
    105  */
    106 ssize_t base64_decode_quartet_using_maps(const base64_maps_t *maps,
    107 				         char dest[3], const char src[4]);
    108 
    109 /**
    110  * base64_decode_tail_using_maps - decode the final bytes of a base64 string using a specific alphabet
    111  * @param maps A base64 maps object (see base64_init_maps)
    112  * @param dest Buffer containing 3 bytes
    113  * @param src Buffer containing 4 bytes - padded with '=' as required
    114  * @param srclen Number of bytes to decode in src
    115  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
    116  * @note sets errno = EDOM if src contains invalid characters
    117  * @note sets errno = EINVAL if src is an invalid base64 tail
    118  */
    119 ssize_t base64_decode_tail_using_maps(const base64_maps_t *maps, char *dest,
    120 				      const char *src, size_t srclen);
    121 
    122 
    123 /* the rfc4648 functions: */
    124 
    125 extern const base64_maps_t base64_maps_rfc4648;
    126 
    127 /**
    128  * base64_encode - Encode a buffer into base64 according to rfc4648
    129  * @param dest Buffer to encode into
    130  * @param destlen Length of the destination buffer
    131  * @param src Buffer to encode
    132  * @param srclen Length of the data to encode
    133  * @return Number of encoded bytes set in dest. -1 on error (and errno set)
    134  * @note dest will be nul-padded to destlen (past any required padding)
    135  * @note sets errno = EOVERFLOW if destlen is too small
    136  *
    137  * This function encodes src according to http://tools.ietf.org/html/rfc4648
    138  *
    139  * Example:
    140  *	size_t encoded_length;
    141  *	char dest[100];
    142  *	const char *src = "This string gets encoded";
    143  *	encoded_length = base64_encode(dest, sizeof(dest), src, strlen(src));
    144  *	printf("Returned data of length %zd @%p\n", encoded_length, &dest);
    145  */
    146 static inline
    147 ssize_t base64_encode(char *dest, size_t destlen,
    148 		      const char *src, size_t srclen)
    149 {
    150 	return base64_encode_using_maps(&base64_maps_rfc4648,
    151 					dest, destlen, src, srclen);
    152 }
    153 
    154 /**
    155  * base64_encode_triplet - encode 3 bytes into base64 according to rfc4648
    156  * @param dest Buffer containing 4 bytes
    157  * @param src Buffer containing 3 bytes
    158  */
    159 static inline
    160 void base64_encode_triplet(char dest[4], const char src[3])
    161 {
    162 	base64_encode_triplet_using_maps(&base64_maps_rfc4648, dest, src);
    163 }
    164 
    165 /**
    166  * base64_encode_tail - encode the final bytes of a source according to rfc4648
    167  * @param dest Buffer containing 4 bytes
    168  * @param src Buffer containing srclen bytes
    169  * @param srclen Number of bytes (<= 3) to encode in src
    170  */
    171 static inline
    172 void base64_encode_tail(char dest[4], const char *src, size_t srclen)
    173 {
    174 	base64_encode_tail_using_maps(&base64_maps_rfc4648, dest, src, srclen);
    175 }
    176 
    177 
    178 /**
    179  * base64_decode - decode An rfc4648 base64-encoded string
    180  * @param dest Buffer to decode into
    181  * @param destlen Length of the destination buffer
    182  * @param src Buffer to decode
    183  * @param srclen Length of the data to decode
    184  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
    185  * @note dest will be nul-padded to destlen
    186  * @note sets errno = EOVERFLOW if destlen is too small
    187  * @note sets errno = EDOM if src contains invalid characters
    188  *
    189  * This function decodes the buffer according to
    190  * http://tools.ietf.org/html/rfc4648
    191  *
    192  * Example:
    193  *	size_t decoded_length;
    194  *	char ret[100];
    195  *	const char *src = "Zm9vYmFyYmF6";
    196  *	decoded_length = base64_decode(ret, sizeof(ret), src, strlen(src));
    197  *	printf("Returned data of length %zd @%p\n", decoded_length, &ret);
    198  */
    199 static inline
    200 ssize_t base64_decode(char *dest, size_t destlen,
    201 		      const char *src, size_t srclen)
    202 {
    203 	return base64_decode_using_maps(&base64_maps_rfc4648,
    204 					dest, destlen, src, srclen);
    205 }
    206 
    207 /**
    208  * base64_decode_quartet - decode the first 4 characters in src into dest
    209  * @param dest Buffer containing 3 bytes
    210  * @param src Buffer containing 4 characters
    211  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
    212  * @note sets errno = EDOM if src contains invalid characters
    213  */
    214 static inline
    215 ssize_t base64_decode_quartet(char dest[3], const char src[4])
    216 {
    217 	return base64_decode_quartet_using_maps(&base64_maps_rfc4648,
    218 						dest, src);
    219 }
    220 
    221 /**
    222  * @brief decode the final bytes of a base64 string from src into dest
    223  * @param dest Buffer containing 3 bytes
    224  * @param src Buffer containing 4 bytes - padded with '=' as required
    225  * @param srclen Number of bytes to decode in src
    226  * @return Number of decoded bytes set in dest. -1 on error (and errno set)
    227  * @note sets errno = EDOM if src contains invalid characters
    228  * @note sets errno = EINVAL if src is an invalid base64 tail
    229  */
    230 static inline
    231 ssize_t base64_decode_tail(char dest[3], const char *src, size_t srclen)
    232 {
    233 	return base64_decode_tail_using_maps(&base64_maps_rfc4648,
    234 					     dest, src, srclen);
    235 }
    236 
    237 /* end rfc4648 functions */
    238 
    239 
    240 
    241 #endif /* CCAN_BASE64_H */