比特币C++实现

比特币的原理看我的另一篇博客,承蒙厚爱,阅读量居然16W+!感谢感谢!

下面是我最近写的一个近乎于完整的模拟比特币的代码,实际上还不够完整,不过已经能实现打包交易进入区块,然后挖矿了。这个程序是只有一个节点在挖矿,所以暂时也不涉及分布式系统的东西,还算比较简单容易理解。这个程序就是整个网络中一个节点的视角。分享出来希望对大家有所帮助。

部署过程就是把代码统统贴过去,要注意的就是代码中有两个文件的路径,要手动改一下,代码中有两个文件的路径,要手动改一下,代码中有两个文件的路径,要手动改一下,重要的事情说三遍,然后就可以运行,观察比特币挖矿过程啦!有问题欢迎提问。

Blockchain.h这个没什么说的,创建一个区块链类

#pragma once
#include"Block.h"
#include<vector>//向量库
class Blockchain
{
public:
	Blockchain();//默认构造函数
	void AddBlock(Block bNew);//增加区块函数
	uint32_t _nDifficulty;//难度值
	vector<Block> _vChain;//保存区块的变量
	Block _GetLastBlock() const;//获取最新的区块,由const关键字,表示输出的内容不可更改
}; 

Blockchain.cpp修改难度值在这里修改Blockchain的构造函数中的nDifficulty就可以了。

#include"Blockchain.h"
Blockchain::Blockchain()
{
	_vChain.emplace_back(Block(0, "Genesis Block"));
	_nDifficulty = 4;//难度值设置3基本上秒出结果,4可以看出差距,5大约要等2分钟左右。
}
void Blockchain::AddBlock(Block bNew)
{
	bNew.sPrevHash = _GetLastBlock().GetHash();
	bNew.MineBlock(_nDifficulty);
	_vChain.push_back(bNew);
	bNew.WriteBlcokToTXT();//调用区块类中的写文件方法
}

Block Blockchain::_GetLastBlock() const
{
	return _vChain.back();
}

Block.h这里是声明区块类

#pragma once
#include<cstdint>//包含了uint32_t等无符号整型
#include<iostream>//标准输入输出库
#include <fstream>
using namespace std;
static time_t first_time = 0;//这个地方是为了记录每个区块产生距离第一个区块的时间而设置的全局变量
//创建区块类
class Block
{
public:
	string sPrevHash;//前一个区块的哈希值
	Block(uint32_t nIndexIn, const string& sDataIn);//构造函数
	string GetHash();//返回哈希值
	void MineBlock(uint32_t nDifficulty);//挖矿,其参数nDifficulty表示指定的难度值
	void NoMineBlock();//不挖矿直接添加区块
	uint32_t _nIndex;//区块索引值,第几个区块,从0开始计算
	int64_t _nNonce;//区块随机数
	string _sData;//区块描述字符
	string _sHash;//区块Hash值
	time_t _tTime;//区块生成时间
	string _CalculateHash() const;//计算Hash值,const保证输出的函数值不能被改变。
	void WriteBlcokToTXT();//将区块数据写入到TXT文件中
};

Block.cpp

#include"Block.h"
#include"sha256.h"
#include"time.h"
#include<sstream>
Block::Block(uint32_t nIndexIn, const string& sDataIn) :_nIndex(nIndexIn), _sData(sDataIn)
//构造函数Block的两个参数为nIndexIn和sDataIn,分别赋值到Block中的_nIndex和_sData(构造函数初始化用法)
{
	_nNonce = -1;//Nounce设置为-1
	_tTime = time(nullptr);//设置时间
	if (nIndexIn == 0)//此处整个时间记录下来是为了记录当前区块生成所需要的时间,而不是当前时间
		first_time = _tTime;
}
string Block::GetHash()//返回哈希值函数的实现
{
	return _sHash;
}
void Block::MineBlock(uint32_t nDifficulty)//挖矿函数,参数为难度值。
{
	//char cstr[nDifficulty + 1];
	char cstr[10 + 1];//这个数组实际上设置多大都可以,但是要大于nDifficulty的值
	for (uint32_t i = 0; i < nDifficulty; ++i)//填充数组,使数组的前nDifficulty位都为0,作为难度。
	{
		cstr[i] = '0';
	}
	cstr[nDifficulty] = '\0';
	string str(cstr);//创建一个string类的对象,初始化为cstr(将字符串数组转换为string类对象)

	do
	{
		_nNonce++;
		_sHash = _CalculateHash();

	} while (_sHash.substr(0, nDifficulty) != str);//substr表示从下标0开始--->nDifficulty的内容
	//要寻找一个Nounce使得总体哈希值的前n位的0(即0的个数)和难度值的个数相同,则挖矿成功。
	cout << "Block mined:" << _sHash << endl;
}

inline string Block::_CalculateHash() const
{
	stringstream ss;//该对象可以通过<<接收多个数据,保存到ss对象中,并通过str方法,将内容赋给一个string对象
	ss << _nIndex << _tTime << _sData << _nNonce << sPrevHash;
	//return sha256(ss.str());
	return sha256(sha256(ss.str()));
}

void Block::WriteBlcokToTXT()//将生成的区块数据输出到一个txt文档中来保存路径自己改
{
	ofstream outfile("out.txt", ios::app);//此处修改保存区块数据的路径
	outfile <<"Index:"<<_nIndex<<endl;
	outfile << "Nonce:" << _nNonce << endl;
	outfile << "_sData:" << _sData << endl;
	outfile << "_sHash:" << _sHash << endl;
	outfile << "sPrevHash:" << sPrevHash << endl;
	outfile << "_tTime:" << _tTime - first_time << endl;
	outfile << endl;
	outfile.close();
}

sha256.h 这是一个哈希算法,没什么说的,网上抄的,这个东西我到现在也没看懂,太深奥了。但是只要知道功能就行了。

#pragma once

#ifndef SHA256_H
#define SHA256_H
#include <string>

class SHA256
{
protected:
	typedef unsigned char uint8;
	typedef unsigned int uint32;
	typedef unsigned long long uint64;

	const static uint32 sha256_k[];
	static const unsigned int SHA224_256_BLOCK_SIZE = (512 / 8);
public:
	void init();
	void update(const unsigned char* message, unsigned int len);
	void final(unsigned char* digest);
	static const unsigned int DIGEST_SIZE = (256 / 8);

protected:
	void transform(const unsigned char* message, unsigned int block_nb);
	unsigned int m_tot_len;
	unsigned int m_len;
	unsigned char m_block[2 * SHA224_256_BLOCK_SIZE];
	uint32 m_h[8];
};

std::string sha256(std::string input);

#define SHA2_SHFR(x, n)    (x >> n)
#define SHA2_ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define SHA2_ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define SHA2_CH(x, y, z)  ((x & y) ^ (~x & z))
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (SHA2_ROTR(x,  2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22))
#define SHA256_F2(x) (SHA2_ROTR(x,  6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25))
#define SHA256_F3(x) (SHA2_ROTR(x,  7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x,  3))
#define SHA256_F4(x) (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10))
#define SHA2_UNPACK32(x, str)                 \
{                                             \
    *((str) + 3) = (uint8) ((x)      );       \
    *((str) + 2) = (uint8) ((x) >>  8);       \
    *((str) + 1) = (uint8) ((x) >> 16);       \
    *((str) + 0) = (uint8) ((x) >> 24);       \
}
#define SHA2_PACK32(str, x)                   \
{                                             \
    *(x) =   ((uint32) *((str) + 3)      )    \
           | ((uint32) *((str) + 2) <<  8)    \
           | ((uint32) *((str) + 1) << 16)    \
           | ((uint32) *((str) + 0) << 24);   \
}
#endif

sha256.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include <fstream>
#include "sha256.h"

const unsigned int SHA256::sha256_k[64] = //UL = uint32
{ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };

void SHA256::transform(const unsigned char* message, unsigned int block_nb)
{
	uint32 w[64];
	uint32 wv[8];
	uint32 t1, t2;
	const unsigned char* sub_block;
	int i;
	int j;
	for (i = 0; i < (int)block_nb; i++) {
		sub_block = message + (i << 6);
		for (j = 0; j < 16; j++) {
			SHA2_PACK32(&sub_block[j << 2], &w[j]);
		}
		for (j = 16; j < 64; j++) {
			w[j] = SHA256_F4(w[j - 2]) + w[j - 7] + SHA256_F3(w[j - 15]) + w[j - 16];
		}
		for (j = 0; j < 8; j++) {
			wv[j] = m_h[j];
		}
		for (j = 0; j < 64; j++) {
			t1 = wv[7] + SHA256_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
				+ sha256_k[j] + w[j];
			t2 = SHA256_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
			wv[7] = wv[6];
			wv[6] = wv[5];
			wv[5] = wv[4];
			wv[4] = wv[3] + t1;
			wv[3] = wv[2];
			wv[2] = wv[1];
			wv[1] = wv[0];
			wv[0] = t1 + t2;
		}
		for (j = 0; j < 8; j++) {
			m_h[j] += wv[j];
		}
	}
}

void SHA256::init()
{
	m_h[0] = 0x6a09e667;
	m_h[1] = 0xbb67ae85;
	m_h[2] = 0x3c6ef372;
	m_h[3] = 0xa54ff53a;
	m_h[4] = 0x510e527f;
	m_h[5] = 0x9b05688c;
	m_h[6] = 0x1f83d9ab;
	m_h[7] = 0x5be0cd19;
	m_len = 0;
	m_tot_len = 0;
}

void SHA256::update(const unsigned char* message, unsigned int len)
{
	unsigned int block_nb;
	unsigned int new_len, rem_len, tmp_len;
	const unsigned char* shifted_message;
	tmp_len = SHA224_256_BLOCK_SIZE - m_len;
	rem_len = len < tmp_len ? len : tmp_len;
	memcpy(&m_block[m_len], message, rem_len);
	if (m_len + len < SHA224_256_BLOCK_SIZE) {
		m_len += len;
		return;
	}
	new_len = len - rem_len;
	block_nb = new_len / SHA224_256_BLOCK_SIZE;
	shifted_message = message + rem_len;
	transform(m_block, 1);
	transform(shifted_message, block_nb);
	rem_len = new_len % SHA224_256_BLOCK_SIZE;
	memcpy(m_block, &shifted_message[block_nb << 6], rem_len);
	m_len = rem_len;
	m_tot_len += (block_nb + 1) << 6;
}

void SHA256::final(unsigned char* digest)
{
	unsigned int block_nb;
	unsigned int pm_len;
	unsigned int len_b;
	int i;
	block_nb = (1 + ((SHA224_256_BLOCK_SIZE - 9)
		< (m_len % SHA224_256_BLOCK_SIZE)));
	len_b = (m_tot_len + m_len) << 3;
	pm_len = block_nb << 6;
	memset(m_block + m_len, 0, pm_len - m_len);
	m_block[m_len] = 0x80;
	SHA2_UNPACK32(len_b, m_block + pm_len - 4);
	transform(m_block, block_nb);
	for (i = 0; i < 8; i++) {
		SHA2_UNPACK32(m_h[i], &digest[i << 2]);
	}
}

std::string sha256(std::string input)
{
	unsigned char digest[SHA256::DIGEST_SIZE];
	memset(digest, 0, SHA256::DIGEST_SIZE);

	SHA256 ctx = SHA256();
	ctx.init();
	ctx.update((unsigned char*)input.c_str(), input.length());
	ctx.final(digest);

	char buf[2 * SHA256::DIGEST_SIZE + 1];
	buf[2 * SHA256::DIGEST_SIZE] = 0;
	for (int i = 0; i < SHA256::DIGEST_SIZE; i++)
		sprintf(buf + i * 2, "%02x", digest[i]);
	return std::string(buf);
}

user.h创建一个用户类

#pragma once
#include <iostream>//标准输入输出库
#include <vector> 
#include <string> 
#include <fstream>
#include<sstream>
#include "BlockChain.h"
#include "sha256.h"
using namespace std;
class User
{
public:
	Blockchain uBlockchain;//当前节点创建一个自己的区块链,因为每个用户都保存一条自己的区块链
	string batchTX();//打包交易
};

user.cpp这里是实现用户的打包交易,通过默克尔树的方式将若干条交易打包。其中300TXdata.txt后面我会贴上,一定注意文件的路径问题,不然可能运行不了。(大神当我没说)。

#include"user.h"
string User::batchTX()
{
    ifstream myfile("300TXdata.txt");//读取txt文档中的300条交易数据
    string temp[300];
    int i = 0;
    if (!myfile.is_open())
    {
        cout << "未成功打开文件" << endl;
    }
    while (getline(myfile, temp[i++]))//将取出来的第一行放在数组中i的位置然后i++
    {
        //cout << temp[i++] << endl;
        getline(myfile, temp[i++]);//将取出来的下一行放在数组i后面的位置然后i++
        //cout << temp[i] << endl;
    }

    for (int i = 0; i < 300; i++)//这是一个伪默克尔树生成过程,为了便于实现,就这样写了。
    //实际上真的默克尔树生成也不难,暂时先这样吧。
    {
        stringstream ss;//该对象可以通过<<接收多个数据,保存到ss对象中,并通过str方法,将内容赋给一个string对象
        ss << temp[0] << temp[i];
        temp[0] = sha256(ss.str());
        //cout << temp[0] << endl;
    }

    myfile.close();
    return temp[0];
}


TestforBitcoin.cpp这就是测试程序了,我是假设100个用户中某个用户挖矿成功了,然后来挖矿。实际上不是这样的过程,而是先挖矿才知道是哪个用户挖矿成功,不过对于一个用户来说,都无所谓了,只是为了模拟的逼真一点,加了个随机数。

#include<iostream>
#include<cstdint>
#include"Blockchain.h"
#include"user.h"
#include<stdio.h>
#include <cstdlib>
#include <ctime>
#include"time.h"
#include"sha256.h"
using namespace std;
int main()
{
	srand((int)time(0));//随机数种子
	Blockchain bChain = Blockchain();//首先创建一个区块链
	User user[100];//创建100个用户
	int miner_id;
	for (int i = 0; i < 100000; i++)//十万次出块,记录出块速度
	{
		miner_id = rand() % 100;
		for (int j = 0; j < 100; j++)
		{
			user[j].uBlockchain = bChain;//把100个节点的区块链初始化。
		}
		user[miner_id].uBlockchain = bChain;//对挖矿区块初始化
		printf("Mining block  %d...\n", i);
		user[miner_id].uBlockchain.AddBlock(Block(i, user[miner_id].batchTX()));
		bChain = user[miner_id].uBlockchain;
		printf("Miner ID is %d...\n", miner_id);
	}
	system("pause");
	return 0;
}

300dataTX.txt这里包含了300条交易,用户A->用户B的转账,以及金额,这个东西我是用一个程序模拟生成的,如果需要这个这个程序我之后再发出来。 

01100SUSPE   10111ZKHWI   79
10010VQJGH   00100UXYMT   34
00011YMAWT   10010XTPCF   43
10101TZZMF   01110SHOLR   51
01011WVQDR   11101VDFBV   59
11001RRPTU   01011QZWRG   68
11100TFFJG   10101TMVIS   76
00010OBWAS   00001OIMYE   85
10000ROVQD   11010RWCPI   93
01111MKMHH   01100LSBFT   1
11011PGDXT   01010OOSVF   10
01001KUCNF   10011JBRMR   18
10110NQTEQ   00101MXICU   26
00000IDKUU   10011HTZSG   35
10100LZJKG   01000KHYJS   43
01110GVABS   11100FDPZE   52
11001JJQRD   00010IQGPH   60
00101EFPHH   10000DMFGT   68
10111GAGYT   00111GIVWF   77
00000BOFOE   11011BWMNR   85
11110EKWEQ   01001ESLDU   93
01110ZYNVU   11110HNCTG   2
01001CUMLG   00000BBTKS   10
10111XPDCR   10100EXSAD   19
00101ADUSD   01111ZLJQH   27
11001DZTIH   11001CHIHT   35
01110YVJZT   01111XCZXF   44
11100BJAPE   00111AQQNQ   20
00010WFZFQ   10000VMOEU   28
10111ZSQWU   00110YAFUG   37
00101UOHMF   11110TWWLS   45
11011WKGCR   01001WRVBD   54
01101RYXTD   10111RFMRH   62
10000UUWJH   00101UBDIT   70
00010PHNSS   10000OXCYE   79
10100SDEIE   01110RLTOQ   87
01011NZCYQ   11100MGKFU   95
11011QNTPU   01010PUJVG   4
11101LJKFF   10111KQALR   12
00010OEJVR   00101NMYCD   21
10000JSAMD   11011IAPSH   29
01100MORCG   01100LWGIT   37
11010HCQSS   11000GRFZE   46
01001JYHJE   10010JFWPQ   54
10111ETYZQ   00100MBNGU   62
00011HHXQT   10011HPMWF   71
10000CDNGF   01011JLDMR   79
01110FZMWR   11101EGUDD   88
11000ANDND   00010HUTTH   96
00101DIUDG   10000CQJJS   4
10111GWTTS   00100FMAAE   13
00001BSKKE   11011AAZQQ   21
11111EOBAQ   01001DVQGU   29
01110ZCAQT   11111YJPXF   38
01000CXRHF   00011BFGNR   46
10110WTIXR   10000WBXED   55
00101ZHGNC   01110ZPWUG   63
11001UDXEG   11000UKNKS   71
01111XROUS   01101XYEBE   80
11100SMNLE   00111RUCRQ   88
00010VIEBP   10001UQTHT   96
10110QWDRT   00110PEKYF   5
00100TSUIF   11110SZJOR   13
11011OGLYR   01000NVAED   22
01101RBKOC   10110QJRVG   30
11001MXBFG   00101LFQLS   38
00010PLRVS   10001OTHCE   47
10100KHQLD   01111JOGKQ   55
01000MDHCP   11100MKXAT   63
11011HQYST   01010PYNRF   72
11101KMXJF   10110KUMHR   80
00011FAOZQ   00101MQDXC   89
10011IWFPC   11011HDUOG   97
00100DSEGG   01101KZTES   5
11010GFVWS   11001FNKUE   14
01000JBUMD   10010IJBLP   22
10101EXKDP   00100DFABT   30
00011HLBTT   10010GSRRF   39
10001CHAJE   01011BOIIR   47
01111FVRAQ   11101ECGYC   56
11010ZQIQC   00011ZYXPG   64
01000CMHHG   10010CUWFS   72
10110XAYXR   00100XHNVD   49
00001AWPND   11010ADEMP   57
11101VKOEP   01000UZDCT   65
01111YFFUT   11101XNUSF   74
01000TBVKE   00011SJLJQ   82
10110WPUBQ   10001VWKZC   91
00110RLLRC   01110QSBPG   99
10000UHKHF   11010TORGS   7
01111PUBYR   01000OCQWD   16
11101SQSOD   00110RYHNP   24
00001NEREP   10001UUGDT   32
10110PAIVS   00101PHXTE   41
00100KWZLE   11111SDOKQ   49
11010NJYCQ   01000NRNAC   58
01111IFOSC   10110PNEQG   66
11101LBFIF   00110KJVHR   74
00011OPEZR   10001NWUXD   83
10101JLVHD   01111ISKNP   91
01000MYMXP   11101LOBET   99
11010HULOS   01001GCAUE   8
11100KQCEE   10110JYRLQ   16
00011FEBUQ   00100ELIBC   25
10011IASLB   11010HHHRF   33
00101CVJBF   01111CDYIR   41
11010FJHSR   11101FRXYD   50
01000AFYID   10011ANOOP   58
10100DTPYO   00100CAFFS   66
00010YPOPS   10000XWDVE   75
10001BKFFE   01010ASULQ   83
01111WYWVQ   11100VGLCC   92
11011ZUVMB   00011YCKSF   0
01000UIMCF   10011TXBIR   8
10110XEDSR   00101WLSZD   17
00000SZCJC   11010RHRPP   25
11001VNSZO   01000UVIGS   33
01111QJRQS   11100XRZWE   42
11001SFIGE   00011SMYMQ   50
10101NTZWP   10001VAODB   59
00110QOYNB   00111QWNTF   67
10000LCPDF   11011SSEJR   75
01110OYGTR   01000NGVAD   84
11111RUFKC   00110QBUQO   92
00001MIWAO   10000LPLGS   0
10111PDNQS   00001OLCXE   9
00101KZLHD   11111JHBNQ   17
11000NNCXP   01001MVSEB   26
01110IJTNB   11111HQJUF   34
11100LXSEF   00110KEHKR   42
00011FTJUQ   10000FAYBC   51
10111IOILC   01110IWPJO   59
01101DCZBO   11111DKOZS   67
11010GYQRS   01001FFFQE   76
01100BMPID   10111ABEGP   84
00000EIGYP   00100DPVWB   93
10010ZDWOB   10000YLMNF   1
00101CRVFE   01110BZLDR   77
11011XNMVQ   11100WUCUC   86
01011AJDLC   10011ZQSKO   94
10100VXCCO   00111UERAS   2
00010YSTSR   10101XAIRD   11
10000SGKJD   01010AWZHP   19
01101VCJZP   11100VKYXB   28
11011QYAPB   01000YFPOF   36
01001TMZGE   10011TTGEQ   44
10111WHPWQ   00101VPFUC   53
00010RDGMC   11011QLWLO   61
11000URFDO   01011TZVBS   69
01110PNWTR   11100OULRD   78
11001SBNJD   00010RQCIP   86
10001NWMAP   10000MEBYB   95
00111QSDQA   00101PASPE   3
10000LGUHE   11011KOJFQ   11
01110OCTXQ   01001NJIVC   20
11110IYKNC   00110IFZMO   28
00000LLAEN   10010LTQCR   36
10111GHZUR   00000GPPSD   45
00101JVQKD   11110IDGJP   53
11001ERPBP   01001DYWZB   62
01110HNGRA   11001GUVPE   70
11100CAXHE   00111BIMGQ   78
00010FWWYQ   10000EELWC   87
10110AKNGB   01110ZACNO   95
01101DGEWN   11110CNTDR   3
11011YCDNR   01001FJSTD   12
01101BPTDD   10111AXJKP   20
00100VLKUO   00101DTAAA   29
10010YHJKA   10001YPZQE   37
00100TVAAE   01110BCPHQ   45
11001WRRRQ   11100WYGXC   54
01011ZEQHB   10010YUFNN   62
10101UAHXN   00111TIWER   70
00011XWGOR   10101WENUD   79
10010SKXEC   01011RRMLP   87
01100VGOUO   11101UNDBA   96
01001QMXMO   11010QCMLA   4
11001TIODA   01001TPDBE   64
11110OEFTD   10101OLUSP   73
00000RREKP   00011RZTIB   81
10110MNVAB   11000LVKYN   90
01110PJMQM   01110ORBPR   98
11001KXLHQ   11010JEAFC   6
01111NTCXC   10000MARVO   15
10101IGANO   00111HWIMA   23
00000LCREZ   10001KKHCD   31
10110GYIUD   01001FGXSP   40
01100JMHKP   11110ITWJB   48
11011EIYBB   00000DPNZN   57
00111GDPRM   10110GLEQQ   65
10101BROHQ   00111BZDGC   73
00011ENFYC   11001EVUWO   82
11100ZBWOO   01111YILNA   58
01100CXVFZ   11101BEKDD   66
11010XSLVD   00000WABTP   75
10101AGCDP   10110ZOSKB   83
00011VCBUA   01100CKQAN   92
11011YQSKM   11011XFHQQ   0
01101TMRAQ   01111ATYHC   8
11010WHIRC   00101VPXXO   17
00000RVZHN   10010YDONZ   25
10100TRYXZ   00100TZNED   33
00011WNPOD   11100WUEUP   42
11001RBGEP   01010RIVLB   50
01111UWEVA   10101TEUBM   59
10010PKVLM   00011OALRQ   67
00000SGMBQ   10011ROCIC   75
10110NCLSB   01100MJAYO   84
01010QQCIN   11010PXROZ   92
11001LLTYZ   01000KTIFD   0
01111OHSPD   10100NPHVP   9
00001JVJFO   00011IDYLA   17
10000MRIVA   11001LYPCM   26
01110HFZMM   01111GMOSQ   34
11000JBPCQ   11010JIFJC   42
01111EWOTB   10000EEEZN   51
10111HKFJN   00110HSVPZ   59
00001CGWZZ   10001BNLGD   67
10111FUVQC   01001EJKWP   76
01100AQMGO   11111HXBMA   84
11000DLDWA   00001CTSDM   93
00110YZCNM   10000FHRTQ   1
10101BVTDP   00110ACIJB   9
00011WRKTB   11000DYZAN   18
11111ZFIKN   01111YMYQZ   26
01100CAZAZ   11111BIPHD   34
11010WOYQC   00001WEGXO   43
10100ZKPHO   10110ZSEFA   51
00100UGGXA   01100UNVWM   60
11011XUFOL   11000WBUMQ   68
01101SPWEP   01110RXLCB   76
11011VLNUB   00101UTCTN   85
00010QZMLN   10011PHBJZ   93
10100TVDBY   00111SCSZC   1
00010OJTRC   11100NYJQO   10
11000RESIO   01010QMIGA   18
01101MAJYA   10100LIZWM   27
11011POAOL   00101OWPNP   35
00001JKZFP   10011JRODB   43
10110MGQVB   01101MNFUN   52
01010HTPMN   11011HBWKZ   60
11000KPGCY   01010KXVAC   68
01111FDXSC   10100ELMRO   77
00001IZWJO   00010HGLHA   85
10001DVMZZ   11001KCCXL   94
00111GIDPL   01101FQTOP   2
11000BECGP   11011IMSEB   10
01010ESTWB   10001DIIUN   19
10110ZOKMM   00110GVZLY   95
00001CKJDY   10010BRYBC   3
10111FXATC   01000EFPSO   12
01101ZTRKO   11111ZBGIA   20
11000CPQAZ   00001CXFYL   29
01110XDHQL   10001XKWPP   37
10100AZFHP   00110ZGNFB   45
00010VMWXA   11000UCMVN   54
11111YINNM   01010XQDMY   62
01101TEMEY   11110SMBCC   70
11011WSDUC   00001VZSSO   79
10110ROUCN   10111QVJJZ   87
00100UJTTZ   01101TRIZL   96
10010PXKJL   11000OFZQP   4
01101STBZP   01110RBQGB   12
11101MHAQA   00100MOPWM   21
00011PDQGM   10011PKGNY   29
10101KZHXY   00111KGXDC   37
00010NMGNB   11101NUWTO   46
11010IIXDN   01011PQMKZ   54
01100LWWUZ   10100KLDAL   63
11011GSNKL   00100NZCQP   71
00001JOEAO   10010IVTHA   79
10101EBDRA   01101LJSXM   88
01010HXUHM   11101GFJNY   96
11000KTLXY   01011JAAEC   4
01110FHJOB   10100EOZUN   13
00010IDAEN   00010HKQLZ   21
10001CQRVZ   11010CGHBL   30
00111FMQLK   01100FUFRP   38
11001AIHBO   11011AQWIA   46
01000DWGSA   10001CDNYM   55
10110YSXIM   00101XZMOY   63
00000BNOYX   10010AVDFB   71
10110WBNPB   01000VJUVN   80
01111ZXEFN   11110YFTLZ   88
11001ULUVZ   00011TAKCL   97
01111XHTMK   10001WOJSO   5
10100SCKCO   00111RKAJA   13
00000VQBTA   11001UYQZM   22
11110PMAJM   01000PUPPY   30
01101SIRZX   11110SPGGB   38
11011NWIQB   00000NDXWN   47
10111QRHGN   10111PZWEZ   55
00101LFYWY   00111SNNVK   64
10010OBXNK   11001NJELO   72
01100JXNDO   01111QEDBA   80
11100MLETA   00100LSUSM   89
00011HGDKL   10000OOLIX   97
10101KUUAX   00110JKJZB   5
00111NQLQB   11101MYAPN   14
11010IMKHN   01011HTZFZ   22
发布了13 篇原创文章 · 获赞 1078 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/zcg_741454897/article/details/104690518