【比特币】十六进制字符串转换成整数数组

0)脚本实现

hex2bvec.sh
echo -n -e $(echo -n $(cat) | sed -e 's/\([a-fA-F0-9]\{2\}\)/\\x\1/g' )

gentoobox harrywu # echo -n c83dc3af1091303168fd1ab44e528d7c941ab49c | hex2bvec.sh > test.dat
gentoobox harrywu # hexdump -C test.dat 
00000000  c8 3d c3 af 10 91 30 31  68 fd 1a b4 4e 52 8d 7c  |.=....01h...NR.||
00000010  94 1a b4 9c                                       |....|
00000014
gentoobox harrywu # 



1) 简化版源代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define DOMAIN_CHECK(c) ('0'<=(c)&&(c)<='9'||'a'<=(c)&&(c)<='f'||'A'<=(c)&&(c)<='F')


int main(int argc, char * argv[])
{
        FILE * fin = stdin;
        FILE * fout= stdout;
        while(!feof(fin)){
                char work []= {0x00, 0x00, 0x00};
                char & c1 = work[0];
                char & c2 = work[1];
                c1 = fgetc(fin);                
                c2 = fgetc(fin);
                if (DOMAIN_CHECK(c1) && DOMAIN_CHECK(c2))
                    fputc(strtoul((char*)work, (char **)NULL, 0x10), fout);
        }
        return 0;
}

编译:

g++ -o h2b -g h2b.cc


测试:

echo -n 0x31323334 | ./h2b


打印:

1234


2) 修订版

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>


#define DOMAIN_CHECK(c) ('0'<=(c)&&(c)<='9'||'a'<=(c)&&(c)<='f'||'A'<=(c)&&(c)<='F')


/* 
 * Converts a string of hexadecimal numbers to an array of bytes. 
 */ 
unsigned char *hexStringToBytes(const char *hexstring) 
{ 
   unsigned char *b; 
   unsigned char work[] = {0x00, 0x00, 0x00}; 
   unsigned char *bytes = NULL; 
   int i; 

   // assert lenght %2 == 0
   bytes = (unsigned char *)calloc(strlen(hexstring) / 2, sizeof *bytes); 
   b = bytes; 
   for (i = 0; i < (int)strlen(hexstring); i += 2) { 
      work[0] = hexstring[i]; 
      work[1] = hexstring[i + 1]; 
      *(b++) = (unsigned char)strtoul((char *)work, (char **)NULL, 16); 
   } 

   return bytes; 
}

int main(int argc, char * argv[])
{
    FILE * fin  = stdin;
    FILE * fout = stdout;
    
    std::string hexstring;
    while(!feof(fin)){
        char c = fgetc(fin);
        if (DOMAIN_CHECK(c))
            hexstring += c;
    }
    
    if (hexstring.length() == 0 ) return -1;
    
    // Pad with '0'
    if (hexstring.length() % 2) hexstring.insert(hexstring.begin(), '0');
    
    // TODO: remove redundant leading '00' 
    
    // TODO: use openssl/bignum to process parse process.
    
    fwrite(hexStringToBytes(hexstring.c_str()), 1, hexstring.length()/2, fout);

    return 0;
}


3) 应用场景

转换比特币的公钥得到比特币地址


3.1) 地址部分1:添加了版本号的地址

echo -n 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 | h2b | sha256sum | h2b | openssl dgst -ripemd160 | awk -F "= " '{ print $2 }' | sed -e 's/\(.*\)/00\1/'

打印:

00010966776006953d5567439e5e39f86a0d273bee


3.2) 地址部分2:地址的checksum

echo -n 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 | h2b | sha256sum | h2b | openssl dgst -ripemd160 | awk -F "= " '{ print $2 }' | sed -e 's/\(.*\)/00\1/' | h2b | sha256sum | sed -e 's/[- ]*//g' | h2b | sha256sum | sed -e 's/[- ]*//g' | sed -e 's/\([0-9a-fA-F]\{8\}\).*/\1/g'

打印:

d61967f6


3.3) 合并

打印:00010966776006953d5567439e5e39f86a0d273beed61967f6


3.4) Base58编码(点击查看)

打印:16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM


4) 参考:

https://forums.gentoo.org/viewtopic-p-1869034.html?sid=a1e50e1208a53f4497f5b9376d7d223d

http://sourceforge.net/projects/hex2bin/files/latest/download

https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses

http://zh.wikipedia.org/wiki/Base58

http://darklaunch.com/tools/base58-encoder-decoder

你可能感兴趣的:(String,serialization,bytes,binary,hex,hex2bin)