⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grand.cpp

📁 一个非常有用的开源代码
💻 CPP
字号:
/*	Copyright (C) 2006, Mike Gashler	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Lesser General Public	License as published by the Free Software Foundation; either	version 2.1 of the License, or (at your option) any later version.	see http://www.gnu.org/copyleft/lesser.html*/#include <string.h>#include "GRand.h"#include "GBigNumber.h"#include <math.h>#include "GMacros.h"#include <stdlib.h>#include "sha1.h"#include "sha2.h"#define HASH_BYTE_SIZE 64GRand::GRand(const unsigned char* pSeedData, int nSeedBytes){	GAssert(nSeedBytes > 0, "Not enough seed bytes");	m_nSeedBytes = nSeedBytes;	m_nBytes = nSeedBytes;	if(m_nBytes < HASH_BYTE_SIZE)		m_nBytes = HASH_BYTE_SIZE;	m_pSeed = new unsigned char[m_nBytes];	memset(m_pSeed, '\0', m_nBytes);	memcpy(m_pSeed, pSeedData, nSeedBytes);		m_pData = new unsigned char[m_nBytes];	memset(m_pData, '\0', m_nBytes);}GRand::~GRand(){	// Ensure that no sensitive info is left in deallocated memory	memset(m_pData, '\0', m_nBytes);	memset(m_pSeed, '\0', m_nBytes);	// Free the memory    delete(m_pData);	delete(m_pSeed);}const unsigned char* GRand::GetRand(){	// Make the new random data    sha512_ctx ctx;	int n = 0;	while(n < m_nBytes)	{		if(m_nBytes - n < HASH_BYTE_SIZE)			n = m_nBytes - HASH_BYTE_SIZE;        // Hash seed + data -> data		sha512_begin(&ctx);        sha512_hash(&m_pSeed[n], HASH_BYTE_SIZE, &ctx);        sha512_hash(&m_pData[n], HASH_BYTE_SIZE, &ctx);        sha512_end(&m_pData[n], &ctx);        // Hash data + seed -> seed		sha512_begin(&ctx);        sha512_hash(&m_pData[n], HASH_BYTE_SIZE, &ctx);        sha512_hash(&m_pSeed[n], HASH_BYTE_SIZE, &ctx);        sha512_end(&m_pSeed[n], &ctx);		n += HASH_BYTE_SIZE;	}	// Shuffle the seed	unsigned char c;	unsigned int nRandPos;	for(n = m_nBytes - sizeof(unsigned int); n >= 0; n--)	{		nRandPos = (*(unsigned int*)&m_pSeed[n]) % m_nBytes;		c = m_pSeed[n];		m_pSeed[n] = m_pSeed[nRandPos];		m_pSeed[nRandPos] = c;	}    return m_pData;}void GRand::AddEntropy(unsigned char* pData, int nSize){	int n;	int nRandPos;	int nSeedPos = m_nBytes - sizeof(unsigned int);	for(n = 0; n < nSize; n++)	{		nRandPos = (*(unsigned int*)&m_pSeed[nSeedPos]) % m_nBytes;		m_pSeed[nRandPos] ^= pData[n];		nSeedPos--;		if(nSeedPos <= 0)			nSeedPos = m_nBytes - sizeof(unsigned int);	}}/*static*/ void GRand::Crypto(unsigned char* pData, int nDataSize, const unsigned char* pPassphrase, int nPassphraseSize, bool bEncrypt){	GRand rng(pPassphrase, nPassphraseSize);	int nPos = 0;	const unsigned char* pPad;	int nBlockStart;	int n;	while(nPos < nDataSize)	{		nBlockStart = nPos;		pPad = rng.GetRand();		if(bEncrypt)			rng.AddEntropy(&pData[nBlockStart], MIN(nPassphraseSize, nDataSize - nBlockStart));		for(n = 0; n < nPassphraseSize && nPos < nDataSize; n++)		{			pData[nPos] ^= pPad[n];			nPos++;		}		if(!bEncrypt)			rng.AddEntropy(&pData[nBlockStart], MIN(nPassphraseSize, nDataSize - nBlockStart));	}}/*static*/ void GRand::Encrypt(unsigned char* pData, int nDataSize, const unsigned char* pPassphrase, int nPassphraseSize){	Crypto(pData, nDataSize, pPassphrase, nPassphraseSize, true);}/*static*/ void GRand::Decrypt(unsigned char* pData, int nDataSize, const unsigned char* pPassphrase, int nPassphraseSize){	Crypto(pData, nDataSize, pPassphrase, nPassphraseSize, false);}/*static*/ void GRand::ShaDigestEntropy(unsigned char* pEntropy, int nEntropyBytes, int nRatio, unsigned int* pResults){	// Scramble the entropy bytes (in case the entropy isn't evenly distributed)	int n;	for(n = nEntropyBytes - 1; n > 1; n--)	{		int nPos = rand() % n;		unsigned char cTmp = pEntropy[n];		pEntropy[n] = pEntropy[nPos];		pEntropy[nPos] = cTmp;	}	// Digest all the 64-byte chunks with sha512	unsigned char* pOutput = (unsigned char*)pResults;	while(nEntropyBytes >= HASH_BYTE_SIZE * nRatio)	{		sha512_ctx ctx;		memset(&ctx, '\0', sizeof(sha512_ctx));		sha512_begin(&ctx);		sha512_hash(pEntropy, 20 * nRatio, &ctx);		sha512_end(pOutput, &ctx);		pEntropy += (HASH_BYTE_SIZE * nRatio);		nEntropyBytes -= (HASH_BYTE_SIZE * nRatio);		pOutput += HASH_BYTE_SIZE;	}	// Digest remaining 20-byte chunks with sha1	while(nEntropyBytes >= 20 * nRatio)	{		SHA_CTX ctx;		memset(&ctx, '\0', sizeof(SHA_CTX));		SHA1_Init(&ctx);		SHA1_Update(&ctx, pEntropy, 20 * nRatio);		SHA1_Final((sha1_byte*)pOutput, &ctx);		pEntropy += (20 * nRatio);		nEntropyBytes -= (20 * nRatio);		pOutput += 20;	}	// Digest whatever's left with sha1	if(nEntropyBytes > 0)	{		unsigned char szDigest[20];		SHA_CTX ctx;		memset(&ctx, '\0', sizeof(SHA_CTX));		SHA1_Init(&ctx);		SHA1_Update(&ctx, pEntropy, nEntropyBytes);		SHA1_Final(szDigest, &ctx);		memcpy(pOutput, szDigest, nEntropyBytes / nRatio);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -