1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
/*
* Copyright 2014 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the standard MIT license. See COPYING for more details.
*/
#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gcrypt.h>
#include "libbase58.h"
static
bool my_sha256(void *digest, const void *data, size_t datasz)
{
gcry_md_hash_buffer(GCRY_MD_SHA256, digest, data, datasz);
return true;
}
static
void usage(const char *prog)
{
fprintf(stderr, "Usage: %s [-c] [-d] [data]\n", prog);
fprintf(stderr, "\t-c Use base58check (default: raw base58)\n");
fprintf(stderr, "\t-d <size> Decode <size> bytes\n");
exit(1);
}
int main(int argc, char **argv)
{
bool b58c = false;
size_t decode = 0;
int opt;
while ( (opt = getopt(argc, argv, "cd:h")) != -1)
{
switch (opt)
{
case 'c':
b58c = true;
b58_sha256_impl = my_sha256;
break;
case 'd':
{
int i = atoi(optarg);
if (i < 0 || (uintmax_t)i >= SIZE_MAX)
usage(argv[0]);
decode = (size_t)i;
break;
}
default:
usage(argv[0]);
}
}
size_t rt;
union {
uint8_t *b;
char *s;
} r;
if (optind >= argc)
{
rt = 0;
r.b = NULL;
while (!feof(stdin))
{
r.b = realloc(r.b, rt + 0x100);
rt += fread(&r.b[rt], 1, 0x100, stdin);
}
if (decode)
while (isspace(r.s[rt-1]))
--rt;
}
else
{
r.s = argv[optind];
rt = strlen(argv[optind]);
}
if (decode)
{
uint8_t bin[decode];
size_t ssz = decode;
if (!b58tobin(bin, &ssz, r.s, rt))
return 2;
if (b58c)
{
int chk = b58check(bin, decode, r.s, rt);
if (chk < 0)
return chk;
if (fwrite(bin, decode, 1, stdout) != 1)
return 3;
}
else
{
// Raw base58 doesn't check length match
uint8_t cbin[ssz];
if (ssz > decode)
{
size_t zeros = ssz - decode;
memset(cbin, 0, zeros);
memcpy(&cbin[zeros], bin, decode);
}
else
memcpy(cbin, &bin[decode - ssz], ssz);
if (fwrite(cbin, ssz, 1, stdout) != 1)
return 3;
}
}
else
{
size_t ssz = rt * 2;
char s[ssz];
bool rv;
if (b58c)
rv = rt && b58check_enc(s, &ssz, r.b[0], &r.b[1], rt-1);
else
rv = b58enc(s, &ssz, r.b, rt);
if (!rv)
return 2;
puts(s);
}
}
|