Difference between revisions of "Dev"
From Obyte Wiki
(copypasta: needs dev tweaking to show correct code colours) |
m (added intro line and wikilink) |
||
| Line 1: | Line 1: | ||
| + | This page is for [[Byteball_Wiki|Byteball]] developer use. It is not dumbed down at all for non-techies. | ||
| + | |||
== Byteball address validation in C++ == | == Byteball address validation in C++ == | ||
<pre> | <pre> | ||
Revision as of 09:27, 12 March 2018
This page is for Byteball developer use. It is not dumbed down at all for non-techies.
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]