Line data Source code
1 : #ifndef HEADER_fd_src_ballet_base58_fd_base58_h 2 : #define HEADER_fd_src_ballet_base58_fd_base58_h 3 : 4 : /* fd_base58.h provides methods for converting between binary and 5 : base58. */ 6 : 7 : #include "../fd_ballet_base.h" 8 : 9 : /* FD_BASE58_ENCODED_{32,64}_{LEN,SZ} give the maximum string length 10 : (LEN) and size (SZ, which includes the '\0') of the base58 cstrs that 11 : result from converting 32 or 64 bytes to base58. */ 12 : 13 14547051 : #define FD_BASE58_ENCODED_32_LEN (44UL) /* Computed as ceil(log_58(256^32 - 1)) */ 14 27471018 : #define FD_BASE58_ENCODED_64_LEN (88UL) /* Computed as ceil(log_58(256^64 - 1)) */ 15 14547051 : #define FD_BASE58_ENCODED_32_SZ (FD_BASE58_ENCODED_32_LEN+1UL) /* Including the nul terminator */ 16 27471018 : #define FD_BASE58_ENCODED_64_SZ (FD_BASE58_ENCODED_64_LEN+1UL) /* Including the nul terminator */ 17 : 18 : FD_PROTOTYPES_BEGIN 19 : 20 : /* Macros for initializing a correctly sized out char 21 : array to encode into. */ 22 : #define FD_BASE58_ENCODE_32_BYTES( bytes, out ) \ 23 63 : char out[ FD_BASE58_ENCODED_32_SZ ]; \ 24 63 : ulong out##_len; \ 25 63 : { \ 26 63 : void const * b = (bytes); \ 27 63 : if( FD_UNLIKELY( !b ) ) { \ 28 0 : strcpy( out, "<NULL>" ); \ 29 0 : out##_len = 6UL; \ 30 0 : } \ 31 63 : else fd_base58_encode_32( bytes, &out##_len, out ); \ 32 63 : } 33 : 34 : #define FD_BASE58_ENCODE_64_BYTES( bytes, out ) \ 35 0 : char out[ FD_BASE58_ENCODED_64_SZ ]; \ 36 0 : ulong out##_len; \ 37 0 : { \ 38 0 : void const * b = (bytes); \ 39 0 : if( FD_UNLIKELY( !b ) ) { \ 40 0 : strcpy( out, "<NULL>" ); \ 41 0 : out##_len = 6UL; \ 42 0 : } \ 43 0 : else fd_base58_encode_64( bytes, &out##_len, out ); \ 44 0 : } 45 : 46 : /* fd_base58_encode_{32, 64}: Interprets the supplied 32 or 64 bytes 47 : (respectively) as a large big-endian integer, and converts it to a 48 : nul-terminated base58 string of: 49 : 50 : 32 to 44 characters, inclusive (not counting nul) for 32 B 51 : 64 to 88 characters, inclusive (not counting nul) for 64 B 52 : 53 : Stores the output in the buffer pointed to by out. If opt_len is 54 : non-NULL, *opt_len == strlen( out ) on return. Returns out. out is 55 : guaranteed to be nul terminated on return. 56 : 57 : Out must have enough space for FD_BASE58_ENCODED_{32,64}_SZ 58 : characters, including the nul terminator. 59 : 60 : The 32 byte conversion is suitable for printing Solana account 61 : addresses, and the 64 byte conversion is suitable for printing Solana 62 : transaction signatures. This is high performance (~100ns for 32B and 63 : ~200ns for 64B without AVX, and roughly twice as fast with AVX), but 64 : base58 is an inherently slow format and should not be used in any 65 : performance critical places except where absolutely necessary. */ 66 : 67 : char * fd_base58_encode_32( uchar const * bytes, ulong * opt_len, char * out ); 68 : char * fd_base58_encode_64( uchar const * bytes, ulong * opt_len, char * out ); 69 : 70 : /* fd_base58_decode_{32, 64}: Converts the base58 encoded number stored 71 : in the cstr `encoded` to a 32 or 64 byte number, which is written to 72 : out in big endian. out must have room for 32 and 64 bytes respective 73 : on entry. Returns out on success and NULL if the input string is 74 : invalid in some way: illegal base58 character or decodes to something 75 : other than 32 or 64 bytes (respectively). The contents of out are 76 : undefined on failure (i.e. out may be clobbered). 77 : 78 : A similar note to the above applies: these are high performance 79 : (~120ns for 32 byte and ~300ns for 64 byte), but base58 is an 80 : inherently slow format and should not be used in any performance 81 : critical places except where absolutely necessary. */ 82 : 83 : uchar * fd_base58_decode_32( char const * encoded, uchar * out ); 84 : uchar * fd_base58_decode_64( char const * encoded, uchar * out ); 85 : 86 : FD_PROTOTYPES_END 87 : 88 : #endif /* HEADER_fd_src_ballet_base58_fd_base58_h */