Dev
From Obyte Wiki
Byteball address validation in C++
<syntaxhighlight lang="cpp"> #include <stdio.h> #include <string.h> #include <openssl/sha.h> #include <type_traits> bool is_byteball_addr(const char *addr) { static const unsigned char offsets[] = { 1, 5, 6, 11, 20, 22, 28, 33, 36, 41, 49, 58, 65, 74, 77, 79, 82, 90, 94, 100, 102, 108, 112, 115, 118, 126, 129, 131, 138, 147, 152, 154 }; const size_t offsets_sz = std::extent<decltype(offsets)>::value; bool bits[32*5]; unsigned char data[16]; unsigned char checksum[4]; { // Base32 validation and decoding. auto b32 = [](char c) -> unsigned char { return ( (c >= 65 && c <= 90) ? (unsigned char) ( c - 65) : (c >= 50 && c <= 55) ? (unsigned char) (26 + c - 50) : 255 ); }; auto isb32 = [](char c) -> bool { return ( (c >= 65 && c <= 90) || (c >= 50 && c <= 55) ); }; size_t i = 0; char *c = (char *) &(*addr); while (isb32(*c) && i < 32) { unsigned char value = b32(*c++); for (size_t j=0; j<5; ++j) { bool bit = (value % 2); value /= 2; bits[5*i + (4-j)] = bit; } ++i; } if (i != 32 || *c) return false; } { // Separation of the checksum from the clean data. auto bits2bytes = [](bool *b, unsigned char *B, size_t sz) -> void { for (size_t i=0; i<sz; ++i) { unsigned char byte = 0; for (size_t j=0; j<8; ++j) { bool bit = b[i*8 + j]; byte ^= (unsigned char) ( (-bit ^ byte) & (1 << (7-j)) ); } B[i] = byte; } }; bool data_bits[128]; bool checksum_bits[32]; size_t start = 0; size_t data_bit_i = 0; size_t checksum_bit_i = 0; for (size_t i=0; i<offsets_sz; ++i) { for (size_t j=start; j<offsets[i]; ++j) { data_bits[data_bit_i++] = bits[j]; } checksum_bits[checksum_bit_i++] = bits[offsets[i]]; start = offsets[i]+1; } memcpy(data_bits+123, bits+155, 5); // Add last fragment. bits2bytes(data_bits, data, 16); bits2bytes(checksum_bits, checksum, 4); } { // Validate the checksum (requires the openssl/sha.h header). SHA256_CTX context; unsigned char md[SHA256_DIGEST_LENGTH]; SHA256_Init(&context); SHA256_Update(&context, (unsigned char*) data, 16); SHA256_Final(md, &context); if (md[ 5] == checksum[0] && md[13] == checksum[1] && md[21] == checksum[2] && md[29] == checksum[3]) return true; } return false; } int main( int argc, char * argv [] ) { int i; for (i = 1; i < argc; ++i ) { bool valid = is_byteball_addr(argv[i]); printf( "%s is %s\n", argv[i], valid ? "VALID." : "INVALID!"); } return 0; } </syntaxhighlight>
byteball github repo[1]