Using an online crc calculator, I know that 32311E333530 (hex) = E558 (hex) for CRC-CCITT (0xFFFF). How can I do this with boost crc?
std::string crc_str = "32311E333530";
boost::crc_16_type result;
result.process_bytes(crc_str.data(), crc_str.length());
std::cout << "checksum = " << result.checksum();
Checksum yields 59589 (decimal) = E8C5 (hex), when E558 (hex) = 58712 (decimal).
What my user manual for serial device says:
unsigned short calculate_crc16(char *data_ptr, unsigned short data_length)
{
unsigned short index;
unsigned short new_crc = 0xFFFF;
//Loop through the entire buffer array of data
for (index = 0; index < data_length; index++)
{
new_crc = (new_crc << 8) ^ crc_table[(new_crc >> 8) ^ (*data_ptr++)];
}
return(new_crc);
}
static const unsigned short crc_table[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
UPDATED
You are confusing ascii string with a byte array. Not the same thing.
This will produce the results you expect:
int main()
{
const unsigned char data[] = {0x32, 0x31, 0x1E, 0x33, 0x35, 0x30};
boost::crc_ccitt_type result;
result.process_bytes(data, 6);
std::cout << "checksum = " << std::hex << result.checksum() << std::endl;
return 0;
}
Prints:
checksum = e558
Old Answer
Because the CRC for that string is definitely xE8C5 or 0xDDF6 for CRC-16 and CRC-CCITT respectively.
Running "32311E333530" through the calculate_crc16 as you have posted from your book's code:
int main()
{
std::string crc_str = "32311E333530";
unsigned result = calculate_crc16(crc_str.c_str(), crc_str.length());
std::cout << "checksum = " << std::hex << result << std::endl;
return 0;
}
prints:
checksum = ddf6
Running it the same string through Boost using the crc_ccitt_type as follows:
int main()
{
std::string crc_str = "32311E333530";
boost::crc_ccitt_type result;
result.process_bytes(crc_str.data(), crc_str.length());
std::cout << "checksum = " << std::hex << result.checksum() << std::endl;
return 0;
}
prints:
checksum = ddf6
So the Boost code matches the output of the code from your serial manual.
Typing 32311E333530 (sans quotes) into this online crc calculator generates the following:
"32311E333530"
1 byte checksum 112
CRC-16 0xE8C5
CRC-16 (Modbus) 0xEAA1
CRC-16 (Sick) 0x9254
CRC-CCITT (XModem) 0x590F
CRC-CCITT (0xFFFF) 0xDDF6
CRC-CCITT (0x1D0F) 0xF065
CRC-CCITT (Kermit) 0xF2EC
CRC-DNP 0x8034
CRC-32 0xFB5DA62C
Notice that CRC-16 is E8C5 - just as your original boost code reports. CRC-CCITT matches as well.
So what's the issue? The boost code for ccitt matches both the manual's code as well as the online tool. The boost results for crc-16 match what my online calculator says as well.
Related
I have written a simple encrypt & decrypt function and everything works. Except sometimes the HexEncoder seems to encode the cipher far too way small. Therefore the decryption fails. But this rarely happens. I have isolated the bug to the HexEncoder since the log Mismatch on encoding is only present when the problem appears. A bad workaround is to call the encrypt function again, which solves the problem. Not sure why, perhaps because of a newly generated IV but this seems unlikely to me.
Am I doing something wrong, undefined behaviour? Or is this a bug from the HexEncoder?
Encrypt function:
// Encrypt data.
template <typename Encryption> static inline
int encrypt(Encryption& m_enc, str_t& encrypted, const str_t& data) {
// Generate & set iv.
CryptoPP::byte iv [CryptoPP::AES::BLOCKSIZE];
rand.GenerateBlock(iv, CryptoPP::AES::BLOCKSIZE);
m_enc.Resynchronize(iv, CryptoPP::AES::BLOCKSIZE);
// Encrypt.
str_t cipher;
cipher.resize(data.len() + CryptoPP::AES::BLOCKSIZE);
cipher.len() = data.len() + CryptoPP::AES::BLOCKSIZE;
CryptoPP::ArraySink encrypt_sink(
(Byte*) cipher.data(),
cipher.len()
);
try {
CryptoPP::StringSource(
data.data(),
true,
new CryptoPP::StreamTransformationFilter(m_enc, new CryptoPP::Redirector(encrypt_sink))
);
} catch (...) {
return crypto::error::encrypt;
}
//print("Cipher 1: ", cipher);
// Set cipher text length now that its known
if (cipher.len() != encrypt_sink.TotalPutLength()) {
print("Mismatch on ciper; expected: ", cipher.len(), " sinked: ", encrypt_sink.TotalPutLength());
}
cipher.resize(encrypt_sink.TotalPutLength());
cipher.len() = encrypt_sink.TotalPutLength();
//print("Cipher 2: ", cipher);
// Encode.
encrypted.resize(cipher.len() * 2);
encrypted.len() = cipher.len() * 2;
CryptoPP::ArraySink encode_sink((Byte*) encrypted.data(), encrypted.len());
try {
CryptoPP::StringSource(
cipher.data(),
true,
new CryptoPP::HexEncoder(
new CryptoPP::Redirector(encode_sink)
)
);
} catch (...) {
encrypted.len() = 0;
return crypto::error::encode;
}
print("Encoded cipher 1: ", encrypted);
// Set encrypted length.
if (encrypted.len() != encode_sink.TotalPutLength()) {
print("BUG -> Mismatch on encoding; expected: ", encrypted.len(), " sinked: ", encode_sink.TotalPutLength());
//str_t shortened;
//shortened.resize(encode_sink.TotalPutLength());
//shortened.concat_no_resize(encrypted.data(), encode_sink.TotalPutLength());
//encrypted.swap(shortened);
return encrypt(m_enc, encrypted, data);
}
encrypted.resize(encode_sink.TotalPutLength());
encrypted.len() = encode_sink.TotalPutLength();
print("Encoded cipher 2: ", encrypted);
// Encode IV.
str_t encoded_iv;
encoded_iv.resize(CryptoPP::AES::BLOCKSIZE * 2);
encoded_iv.len() = CryptoPP::AES::BLOCKSIZE * 2;
CryptoPP::ArraySink iv_sink((Byte*) encoded_iv.data(), encoded_iv.len());
try {
CryptoPP::ArraySource(
iv,
CryptoPP::AES::BLOCKSIZE,
true,
new CryptoPP::HexEncoder(
new CryptoPP::Redirector(iv_sink)
)
);
} catch (...) {
encrypted.len() = 0;
return crypto::error::encode;
}
// Set encoded iv length.
if (encoded_iv.len() != iv_sink.TotalPutLength()) {
print("Mismatch on encoding iv; expected: ", encoded_iv.len(), " sinked: ", iv_sink.TotalPutLength());
}
encoded_iv.resize(iv_sink.TotalPutLength());
encoded_iv.len() = iv_sink.TotalPutLength();
print("Encoded IV: ", encoded_iv);
// Concat IV.
encoded_iv.concat(encrypted);
encrypted.swap(encoded_iv);
return 0;
}
Decrypt function:
// Decrypt data.
template <typename Decryption> static inline
int decrypt(Decryption& m_dec, str_t& decrypted, const str_t& data) {
// Decode.
str_t decoded;
decoded.resize(data.len() / 2);
decoded.len() = data.len() / 2;
try {
CryptoPP::StringSource(
data.data(),
true,
new CryptoPP::HexDecoder(
new CryptoPP::ArraySink((Byte*) decoded.data(), decoded.len())
)
);
} catch (...) {
return crypto::error::decode;
}
// Skip for now.
m_dec.Resynchronize((Byte*) decoded.data(), CryptoPP::AES::BLOCKSIZE);
// Recovered text will be less than cipher text
decrypted.resize(decoded.len() - CryptoPP::AES::BLOCKSIZE);
decrypted.len() = decoded.len() - CryptoPP::AES::BLOCKSIZE;
CryptoPP::ArraySink rs((Byte*) decrypted.data(), decrypted.len());
try {
CryptoPP::StringSource(
(Byte*) decoded.data() + CryptoPP::AES::BLOCKSIZE,
decoded.len(),
true,
new CryptoPP::StreamTransformationFilter(
m_dec,
new CryptoPP::Redirector(rs),
CryptoPP::BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING
)
);
} catch (...) {
decrypted.len() = 0;
return crypto::error::decrypt;
}
// Set recovered text length now that its known
decrypted.resize(rs.TotalPutLength());
decrypted.len() = rs.TotalPutLength();
return 0;
}
Testing:
...
str_t data = "Hello World!", encrypted, decrypted;
aes.encrypt(encrypted, data);
aes.decrypt(decrypted, encrypted);
print("Encrypted: ", encrypted);
print("Decrypted: ", decrypted);
This are the normal logs (without the bug occurence):
Mismatch on ciper; expected: 28 sinked: 16
Encoded cipher 1: 04A2C4FB074F6ACBA996239224BD5F77
Encoded cipher 2: 04A2C4FB074F6ACBA996239224BD5F77
Encoded IV: 02466AEBCF4AC2066CE2E144FC5B71C8
Encrypted: 02466AEBCF4AC2066CE2E144FC5B71C804A2C4FB074F6ACBA996239224BD5F77
Decrypted: Hello World!
This are the logs when the bug occurs (with the recursive encrypt call commented out):
Decoded: Hello World!
Mismatch on ciper; expected: 28 sinked: 16
Encoded cipher 1: C97BFE
BUG -> Mismatch on encoding; expected: 32 sinked: 6
Encoded cipher 2: C97BFE
Encoded IV: 06E05C3DAE3E9D6DAC8971E5C9CA0A1A
Encrypted: 06E05C3DAE3E9D6DAC8971E5C9CA0A1AC97BFE
Decrypted:
This are the logs when the bug occurs with the workaround:
Mismatch on ciper; expected: 28 sinked: 16
Encoded cipher 1: A0
BUG -> Mismatch on encoding; expected: 32 sinked: 2
Mismatch on ciper; expected: 28 sinked: 16
Encoded cipher 1: 883A8A644E5B50067A
BUG -> Mismatch on encoding; expected: 32 sinked: 18
Mismatch on ciper; expected: 28 sinked: 16
Encoded cipher 1: 58AD2010C761215422F89D42FC2F2396
Encoded cipher 2: 58AD2010C761215422F89D42FC2F2396
Encoded IV: BE361B7D8C9144052220E143AD54CB63
Encrypted: BE361B7D8C9144052220E143AD54CB6358AD2010C761215422F89D42FC2F2396
Decrypted: Hello World!
I don't know what a str_t is, but since it has a .data() method I assume that returns the underlying char*. Since you are not specifying a length in the CryptoPP::StringSource, it assumes the input stops at the first NUL byte. For plaintext input this is often fine but cipher data MAY contain embedded NULs.
Instead, either pass the length of your cipher explicitly:
CryptoPP::StringSource(
cipher.data(),
cipher.len(),
true,
new CryptoPP::HexEncoder(
new CryptoPP::Redirector(encode_sink)
)
);
Or, better, convert the str_t into a std::string that knows its own size and pass that as argument.
I need to implement CRC16-CCITT for HDLC, as part of developing some feature to control external HW (some type of LTE antenna).
The problem is that even though I have found many online implementations for CRC16-CCITT, the output values don't match the CRC values the HW vendor sent us.
For example, this is the first HDLC frame (named "Device Scan") which should be sent to the device, in hexadecimal format:
7EFFBF81F02A0113000000000000000000000000000000000000000313000000000000000000000000000000000000007F0F7E
As can be seen, the 7E in the start and end are the delimiters, and the last 4 hexadecimal characters are the CRC - which means 0x7F0F is the CRC result.
However, many online CRC calculators produce the result 0x6CC3
(take a look here for example: http://www.zorc.breitbandkatze.de/crc.html , https://www.lammertbies.nl/comm/info/crc-calculation)
Same goes for another command, which is the matching "receive" command for the above.
the RCV command is:
7E00BF81F018010F4B4D4B3032313941303035335A585806024B4D040130F1ED7E
which means that 0xF1ED is the CRC, and again it isn't what i see in other calculators, which produce 0xD814.
We have asked the vendor for clarifications, and he sent us this lookup table they are using:
crc table:
{
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
}
This doesn't look like the regular table of CRC16-CCITT i found online, such as:
static const unsigned short CRC_CCITT_TABLE[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
i tried to use their table instead of mine, in our CRC implementation, but we still get different results than theirs.
Does anyone understand what is going on here?
which CRC is the actual correct HDLC CRC16-CCITT?
What the the correct result of CRC16-CCITT for the above frames?
Thanks a lot guys!
I initially thought the poly was 0x1189, but instead it's a bit reversal of 0x1021 = 0x8408, which is seen at table[0x80]. Using the online CRC calculator linked to below, it's the predefined CRC_X_25, poly = 0x1021, input reflected, result reflected, initial value 0xFFFF, final xor 0xFFFF. Click on "show reflected lookup table", and you will get the same table as the vendor's table when you calculate a CRC using the calculator.
When appending the CRC to data, the CRC is appended as lower byte, upper byte. So a CRC of 0xEDF1 is appended as: 0xF1, 0xED, and a CRC of 0x0F7F, is appended as: 0x7F, 0x0F.
Because the CRC is post complemented (xorout = 0xFFFF), if checking the CRC by recalculating it on data + CRC, if there are no errors, the CRC will be a non-zero constant, 0x0F47.
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
Example code:
#include <iostream>
#include <iomanip>
uint16_t crctbl[256];
void gentbl()
{
uint16_t crc, i, j;
for(j = 0; j < 0x100; j++){
crc = j;
for(i = 0; i < 8; i++)
crc = (crc>>1)^((0-(crc&1))&0x8408);
crctbl[j] = crc;
}
}
uint16_t crc16(uint8_t * bfr, size_t size)
{
uint16_t crc = 0xffff;
while (size--)
crc = (crc>>8)^crctbl[(crc^*bfr++)&0xff];
return(crc ^ 0xffff);
}
int main(int argc, char**argv)
{
uint16_t crc;
// bfr has 2 trailing zeroes to store crc into
uint8_t bfr[] = {0x00,0xBF,0x81,0xF0,0x18,0x01,0x0F,0x4B,
0x4D,0x4B,0x30,0x32,0x31,0x39,0x41,0x30,
0x30,0x35,0x33,0x5A,0x58,0x58,0x06,0x02,
0x4B,0x4D,0x04,0x01,0x30,0x00,0x00};
gentbl();
crc = crc16(bfr, sizeof(bfr)-2);
std::cout << std::hex << crc << std::endl;
bfr[sizeof(bfr)-2] = crc&0xff;
bfr[sizeof(bfr)-1] = crc>>8;
crc = crc16(bfr, sizeof(bfr));
std::cout << std::hex << crc << std::endl;
if(crc != 0xf47)
std::cout << "error" << std::endl;
return(0);
}
First: I am a newbite to altcoin development, next to generate an altcoin from litecoin,
1- I have made a clone of litecoin using git clone https://githubcom/litecoin-project/lotecoin.git
2- I changed some of chain and coin parameters in chainparams.cpp as below:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparams.h"
#include "consensus/merkle.h"
#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"
#include <assert.h>
#include "chainparamsseeds.h"
#include "arith_uint256.h"
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;
CBlock genesis;
genesis.nTime = nTime;
genesis.nBits = nBits;
genesis.nNonce = nNonce;
genesis.nVersion = nVersion;
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
return genesis;
}
/**
* Build the genesis block. Note that the output of its generation
* transaction cannot be spent since it did not originally exist in the
* database.
*
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, *nNonce=2083236893, vtx=1)
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
* CTxIn(COutPoint(000000, -1), coinbase *04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420**666f722062616e6b73)
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "Tehran Times, Stonica wins finally";
const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
consensus.vDeployments[d].nStartTime = nStartTime;
consensus.vDeployments[d].nTimeout = nTimeout;
}
/**
* Main network
*/
/**
* What makes a good checkpoint block?
* + Is surrounded by blocks with reasonable timestamps
* (no blocks before with a timestamp after, none after with
* timestamp before)
* + Contains no strange transactions
*/
class CMainParams : public CChainParams {
public:
CMainParams() {
strNetworkID = "main";
consensus.nSubsidyHalvingInterval = 840000;
consensus.BIP34Height = 710000;
consensus.BIP34Hash = uint256S("00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5");
consensus.BIP65Height = 918684; // bab3041e8977e0dc3eeff63fe707b92bde1dd449d8efafb248c27c8264cc311a
consensus.BIP66Height = 811879; // 7aceee012833fa8952f8835d8b1b3ae233cd6ab08fdb27a771d2bd7bdc491894
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 6048; // 75% of 8064
consensus.nMinerConfirmationWindow = 8064; // nPowTargetTimespan / nPowTargetSpacing * 4
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1485561600; // January 28, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000ba50a60f8b56c7fe0");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x29c8c00e1a5f446a6364a29633d3f1ee16428d87c8d3851a1c570be8170b04c2"); //1259849
/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
* a large 32-bit integer with any alignment.
*/
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0xd0;
pchMessageStart[2] = 0xb6;
pchMessageStart[3] = 0xdb;
nDefaultPort = 9335;
nPruneAfterHeight = 100000;
//static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
genesis = CreateGenesisBlock(1511279793, 1251189192, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
/*
// calculate Genesis Block
// Reset genesis
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash() != consensus.hashGenesisBlock)) {
LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = 0;
// This will figure out a valid hash and Nonce if you're
// creating a different genesis block:
// uint256 hashTarget = CBigNum().SetCompact(genesis.nBits).getuint256();
// hashTarget.SetCompact(genesis.nBits, &fNegative, &fOverflow).getuint256();
// while (genesis.GetHash() > hashTarget)
while (UintToArith256(genesis.GetHash()) > hashTarget)
{
++genesis.nNonce;
if (genesis.nNonce == 0)
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if (genesis.nNonce % 10000 == 0)
{
LogPrintf("Mainnet: nonce %08u: hash = %s \n", genesis.nNonce, genesis.GetHash().ToString().c_str());
// std::cout << strNetworkID << " nonce: " << genesis.nNonce << " time: " << genesis.nTime << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
// Mainnet --- nonce: 296277 time: 1390095618 hash: 000000bdd771b14e5a031806292305e563956ce2584278de414d9965f6ab54b0
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
*/
//printf("%s\n",consensus.hashGenesisBlock.Tostring().c_str());
std::cout << std::string("ENTER:\n");
assert(consensus.hashGenesisBlock == uint256S("0x00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5"));
assert(genesis.hashMerkleRoot == uint256S("0xf8621e34b0dcd43361fe589702e06aa79992229bfbca57d058d8561635c30fbe"));
std::cout << std::string("PASSED:\n");
printf("min nBit: %08x\n", consensus.powLimit);
// Note that of those with the service bits flag, most only support a subset of possible options
//vSeeds.emplace_back("seed-a.stonicacoin.loshan.co.uk", true);
//vSeeds.emplace_back("dnsseed.thrasher.io", true);
//vSeeds.emplace_back("dnsseed.stonicacointools.com", true);
//vSeeds.emplace_back("dnsseed.stonicacoinpool.org", true);
//vSeeds.emplace_back("dnsseed.koin-project.com", false);
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,127);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,65);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,56);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,176);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
fDefaultConsistencyChecks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
checkpointData = (CCheckpointData) {
{
{ 0, uint256S("0x00000000b2c50d03d4d0bdd38681775ce522f137518145d6b3c913b7dd4423e5")},
}
};
chainTxData = ChainTxData{
// Data as of block db42d00d824950a125f9b08b6b6c282c484781562fa8b3bd29d6ce4a2627c348 (height 1259851).
1502955334, // * UNIX timestamp of last known number of transactions
1, // * total number of transactions between genesis and that timestamp
// (the tx=... number in the SetBestChain debug.log lines)
0.00 // * estimated number of transactions per second after that timestamp
};
}
};
/**
* Testnet (v3)
*/
class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
strNetworkID = "test";
consensus.nSubsidyHalvingInterval = 840000;
consensus.BIP34Height = 76;
consensus.BIP34Hash = uint256S("8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573");
consensus.BIP65Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.BIP66Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1517356801; // January 31st, 2018
// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1483228800; // January 1, 2017
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1517356801; // January 31st, 2018
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000000000000364b0cbc3568");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0xad8ff6c2f5580d2b50bd881e11312425ea84fa99f322bf132beb722f97971bba"); //153490
pchMessageStart[0] = 0xfd;
pchMessageStart[1] = 0xd2;
pchMessageStart[2] = 0xc8;
pchMessageStart[3] = 0xf1;
nDefaultPort = 19335;
nPruneAfterHeight = 1000;
genesis = CreateGenesisBlock(1511279793, 0, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
//assert(consensus.hashGenesisBlock == uint256S("0x"));
//assert(genesis.hashMerkleRoot == uint256S("0x"));
vFixedSeeds.clear();
vSeeds.clear();
// nodes with support for servicebits filtering should be at the top
//vSeeds.emplace_back("testnet-seed.stonicacointools.com", true);
//vSeeds.emplace_back("seed-b.stonicacoin.loshan.co.uk", true);
//vSeeds.emplace_back("dnsseed-testnet.thrasher.io", true);
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,58);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));
fDefaultConsistencyChecks = false;
fRequireStandard = false;
fMineBlocksOnDemand = false;
checkpointData = (CCheckpointData) {
{
{0, uint256S("")},
}
};
chainTxData = ChainTxData{
// Data as of block 3351b6229da00b47ad7a8d7e1323b0e2874744b5296e3d6448293463ab758624 (height 153489)
//1502953751,
//382986,
//0.01
};
}
};
/**
* Regression test
*/
class CRegTestParams : public CChainParams {
public:
CRegTestParams() {
strNetworkID = "regtest";
consensus.nSubsidyHalvingInterval = 150;
consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = true;
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL;
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x00");
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda;
nDefaultPort = 19444;
nPruneAfterHeight = 1000;
genesis = CreateGenesisBlock(1511279793, 0, 0x1d00ffff , 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x9"));
assert(genesis.hashMerkleRoot == uint256S("0x"));
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds.
fDefaultConsistencyChecks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
checkpointData = (CCheckpointData) {
{
{0, uint256S("530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9")},
}
};
chainTxData = ChainTxData{
0,
0,
0
};
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SCRIPT_ADDRESS2] = std::vector<unsigned char>(1,58);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
}
};
static std::unique_ptr<CChainParams> globalChainParams;
const CChainParams &Params() {
assert(globalChainParams);
return *globalChainParams;
}
std::unique_ptr<CChainParams> CreateChainParams(const std::string& chain)
{
if (chain == CBaseChainParams::MAIN)
return std::unique_ptr<CChainParams>(new CMainParams());
else if (chain == CBaseChainParams::TESTNET)
return std::unique_ptr<CChainParams>(new CTestNetParams());
else if (chain == CBaseChainParams::REGTEST)
return std::unique_ptr<CChainParams>(new CRegTestParams());
throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}
void SelectParams(const std::string& network)
{
SelectBaseParams(network);
globalChainParams = CreateChainParams(network);
}
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout);
}
As you may know the bitcoin developers has omitted the genesis block mining code from source code published in github, but I fortunately found some piece of code in related blogs and it worked, then I have calculated the new Genesis hash, Merkelroot hash and Nonce and put into code as you can see above.
The code was compiled correctly and I have not received Assertion failed message for Genesis block but I received another error which you can see in debug.log as below:
2017-12-15 07:31:33
2017-12-15 07:31:33 Stonicacoin version v0.15.0.1-gba8ed3a93be
2017-12-15 07:31:33 InitParameterInteraction: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1
2017-12-15 07:31:33 Assuming ancestors of block 29c8c00e1a5f446a6364a29633d3f1ee16428d87c8d3851a1c570be8170b04c2 have valid signatures.
2017-12-15 07:31:33 Using the 'standard' SHA256 implementation
2017-12-15 07:31:33 Using RdRand as an additional entropy source
2017-12-15 07:31:33 Default data directory /home/kevin/.stonicacoin
2017-12-15 07:31:33 Using data directory /home/kevin/.stonicacoin
2017-12-15 07:31:33 Using config file /home/kevin/.stonicacoin/stonicacoin.conf
2017-12-15 07:31:33 Using at most 125 automatic connections (1024 file descriptors available)
2017-12-15 07:31:33 Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
2017-12-15 07:31:33 Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
2017-12-15 07:31:33 Using 8 threads for script verification
2017-12-15 07:31:33 scheduler thread start
2017-12-15 07:31:33 HTTP: creating work queue of depth 16
2017-12-15 07:31:33 No rpcpassword set - using random cookie authentication
2017-12-15 07:31:33 Generated RPC authentication cookie /home/kevin/.stonicacoin/.cookie
2017-12-15 07:31:33 HTTP: starting 4 worker threads
2017-12-15 07:31:33 Cache configuration:
2017-12-15 07:31:33 * Using 2.0MiB for block index database
2017-12-15 07:31:33 * Using 8.0MiB for chain state database
2017-12-15 07:31:33 * Using 440.0MiB for in-memory UTXO set (plus up to 4.8MiB of unused mempool space)
2017-12-15 07:31:33 init message: Loading block index...
2017-12-15 07:31:33 Opening LevelDB in /home/kevin/.stonicacoin/blocks/index
2017-12-15 07:31:33 Opened LevelDB successfully
2017-12-15 07:31:33 Using obfuscation key for /home/kevin/.stonicacoin/blocks/index: 0000000000000000
2017-12-15 07:31:33 LoadBlockIndexDB: last block file = 0
2017-12-15 07:31:33 LoadBlockIndexDB: last block file info: CBlockFileInfo(blocks=0, size=0, heights=0...0, time=1970-01-01...1970-01-01)
2017-12-15 07:31:33 Checking all blk files are present...
2017-12-15 07:31:33 LoadBlockIndexDB: transaction index disabled
2017-12-15 07:31:33 Initializing databases...
2017-12-15 07:31:33 Pre-allocating up to position 0x1000000 in blk00000.dat
2017-12-15 07:31:33 Opening LevelDB in /home/kevin/.stonicacoin/chainstate
2017-12-15 07:31:33 Opened LevelDB successfully
2017-12-15 07:31:33 Wrote new obfuscate key for /home/kevin/.stonicacoin/chainstate: 77f259e28117a4e1
2017-12-15 07:31:33 Using obfuscation key for /home/kevin/.stonicacoin/chainstate: 77f259e28117a4e1
2017-12-15 07:31:33 init message: Rewinding blocks...
2017-12-15 07:31:33 block index 11ms
2017-12-15 07:31:33 No wallet support compiled in!
2017-12-15 07:31:33 ERROR: ReadBlockFromDisk: Errors in block header at CBlockDiskPos(nFile=0, nPos=8)
2017-12-15 07:31:33 *** Failed to read block
2017-12-15 07:31:33 Error: Error: A fatal internal error occurred, see debug.log for details
I found that this error(eg. ERROR: ReadBlockFromDisk: Errors in block header at CBlockDiskPos(nFile=0, nPos=8) ) occur in CheckProofOfWork function which is in pow.cpp, Any recommendation is appreciated.
After struggling too much I finally solve the issue:
1)
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
should be set to a lower limit like
consensus.powLimit = uint256S("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
and set genesis.nBits to 0x1f00ffff when in CreateGenesisBlock function like
genesis = CreateGenesisBlock(1519394018, 6446, 0x1f0fffff, 1, 1 * COIN);
For Testnet I used 0x1f0fffff.
2) For Bitcoin v0.15+ the following genesis block generating code should be used:
// calculate Genesis Block
// Reset genesis
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash(consensus) != consensus.hashGenesisBlock)) {
// LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = ArithToUint256(0);
while (UintToArith256(genesis.GetHash(consensus)) > hashTarget)
{
genesis.nNonce = ArithToUint256(UintToArith256(genesis.nNonce) + 1);
if (genesis.nNonce == ArithToUint256(arith_uint256(0)))
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if ((int)genesis.nNonce.GetUint64(0) % 10000 == 0)
{
std::cout << strNetworkID << " hashTarget: " << hashTarget.ToString() << " nonce: " << genesis.nNonce.ToString() << " time: " << genesis.nTime << " hash: " << genesis.GetHash(consensus).ToString().c_str() << "\r";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce.ToString() << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash(consensus).ToString().c_str() << "\n";
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
For the older codebases the genesis block generating code that #Hossein Mirheydari given is working. Actually you should check
genesis.nNonce = ArithToUint256(arith_uint256(nNonce));
definition in
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward);
function to see if it's given as above or as
genesis.nNonce = nNonce;
If it's given as the latter one then use #Hossein Mirheydari's genesis block generation code. If it's given with ArithToUint256() function use the genesis block generation code I pasted above.
3) This genesis block generation should be done for Mainnet and Testnet seperately. Regtest does not need a genesis block generation since it's pow limit is so small (but you may want to do it anyway just to be sure of everything works fine) and so
printf("TEST GENESIS HASH: %s\n",consensus.hashGenesisBlock.ToString().c_str());
printf("TEST MERKLE ROOT: %s\n",genesis.hashMerkleRoot.ToString().c_str());
assert(consensus.hashGenesisBlock == uint256S("0x0009b0d830d5e13f7a39dd6c30cae59ff95e1a4aa4fc22435dc1fcb92561cd8e"));
assert(genesis.hashMerkleRoot == uint256S("0xf1552bf3d58facdc6d7ec8461aff6b0560d20eb16e41749b9f8f5a7eaa1220fc"));
inserting the printed consensus.hashGenesisBlock and genesis.hashMerkleRoot into
assert(consensus.hashGenesisBlock == uint256S("0x0009b0d830d5e13f7a39dd6c30cae59ff95e1a4aa4fc22435dc1fcb92561cd8e"));
assert(genesis.hashMerkleRoot == uint256S("0xf1552bf3d58facdc6d7ec8461aff6b0560d20eb16e41749b9f8f5a7eaa1220fc"));
statements works.
4) If you have
consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.powLimitLegacy = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
like the ones in Bitcoin Gold (which I now am using) use the same pow limit as consensus.powLimit.
Thus, with genesis generation code, genesis block is generated. With low pow limit, genesis block be in pow range and so no PoW validation error will occur anymore.
I hope this will help.
On the main branch at this time the solution for me was to change the GetHash() to GetPoWHash(). I also followed the answer of #Bedri Ozgur Guler for the PoWLimit and nBits:
consensus.hashGenesisBlock = uint256S("0x");
std::cout << std::string("Begin calculating Mainnet Genesis Block:\n");
if (true && (genesis.GetHash() != consensus.hashGenesisBlock)) {
LogPrintf("Calculating Mainnet Genesis Block:\n");
arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
uint256 hash;
genesis.nNonce = 0;
while (UintToArith256(genesis.GetPoWHash()) > hashTarget) // ---> Here GetPoWHash() !!
{
++genesis.nNonce;
if (genesis.nNonce == 0)
{
LogPrintf("NONCE WRAPPED, incrementing time");
std::cout << std::string("NONCE WRAPPED, incrementing time:\n");
++genesis.nTime;
}
if (genesis.nNonce % 10000 == 0)
{
LogPrintf("Mainnet: nonce %08u: hash = %s \n", genesis.nNonce, genesis.GetHash().ToString().c_str());
// std::cout << strNetworkID << " nonce: " << genesis.nNonce << " time: " << genesis.nTime << " hash: " << genesis.GetHash().ToString().c_str() << "\n";
}
}
std::cout << "Mainnet ---\n";
std::cout << " nonce: " << genesis.nNonce << "\n";
std::cout << " time: " << genesis.nTime << "\n";
std::cout << " hash: " << genesis.GetHash().ToString().c_str() << "\n"; // The hash for the assert is GetHash()
std::cout << " merklehash: " << genesis.hashMerkleRoot.ToString().c_str() << "\n";
// Mainnet --- nonce: 296277 time: 1390095618 hash: 000000bdd771b14e5a031806292305e563956ce2584278de414d9965f6ab54b0
}
std::cout << std::string("Finished calculating Mainnet Genesis Block:\n");
Looking in the file validation.cpp on the method ReadBlockFromDisk I found that the hash that must pass the CheckProofOfWork is the PoWHash
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams)
{
// ...
// Check the header
if (!CheckProofOfWork(block.GetPoWHash(), block.nBits, consensusParams))
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
}
EDIT: Tested with the litecoin PoWLimit and nBits values and It worked.
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
genesis = CreateGenesisBlock(1619494752, 721332, 0x1e0ffff0, 1, 50 * COIN);
FreddyJS, genesis.GetPoWHash() worked nicely for litecoin, the hashes match what I would get with GenesisH0. But unfortunately it doesn't work on another coin I'm testing, gives an error on compilation. Any ideas?
error: no matching function for call to ‘CBlock::GetPoWHash()’
After some digging, the code is different than litecoin. In validation.cpp:
// Check the header
if (!CheckProofOfWork(block.GetPoWHash(nHeight), block.nBits, consensusParams))
return error("ReadBlockFromDisk: Errors in block header at %s, %d", pos.ToString(), nHeight);
GetPoWHash(nHeight) vs GetPoWHash() in litecoin.
This is code of Raptoreum
https://github.com/Raptor3um/raptoreum/blob/master/src/chainparams.cpp
Them try debug Dash to find genesis block hash
Them change only Time
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
const char* pszTimestamp = "The Times 22/Jan/2018 Raptoreum is name of the game for new generation of firms";
const CScript genesisOutputScript = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
The Dask use X11
###
static void FindMainNetGenesisBlock(uint32_t nTime, uint32_t nBits, const char* network)
{
CBlock block = CreateGenesisBlock(nTime, 0, nBits, 4, 5000 * COIN);
arith_uint256 bnTarget;
bnTarget.SetCompact(block.nBits);
for (uint32_t nNonce = 0; nNonce < UINT32_MAX; nNonce++) {
block.nNonce = nNonce;
uint256 hash = block.GetPOWHash();
if (nNonce % 48 == 0) {
printf("\nrnonce=%d, pow is %s\n", nNonce, hash.GetHex().c_str());
}
if (UintToArith256(hash) <= bnTarget) {
printf("\n%s net\n", network);
printf("\ngenesis is %s\n", block.ToString().c_str());
printf("\npow is %s\n", hash.GetHex().c_str());
printf("\ngenesisNonce is %d\n", nNonce);
std::cout << "Genesis Merkle " << block.hashMerkleRoot.GetHex() << std::endl;
return;
}
}
// This is very unlikely to happen as we start the devnet with a very low difficulty. In many cases even the first
// iteration of the above loop will give a result already
error("%sNetGenesisBlock: could not find %s genesis block",network, network);
assert(false);
}
###
It seems the -reindex parameter solves avoids the issue and gives the main reason of error which is Genesis Block does not have valid PoW. It is suggested in BITCOIN CORE CRASHED #8081 (https://github.com/bitcoin/bitcoin/issues/8081) for a solution for the issue of a corrupted blockchain data:
sipa commented on 21 May 2016
Start bitcoind or bitcoin-qt with
the -reindex command line option. This will throw away the indexes and
rebuild them from scratch, but reuse the blocks on disk in so far as
they are usable.
I am using the following function to generate a CRC sum and it doesn't appear to be returning the same checksum when compared to online CRC-CCITT calculators.
This function specifically uses the XMODEM CRC generation with a 0x8408 polynomial with an initial fcs of 0xFFFF.
uint16_t crc16(uint8_t byte, uint16_t fcs)
{
uint8_t bit;
for(bit=0; bit<8; bit++)
{
fcs ^= (byte & 0x01);
fcs = (fcs & 0x01) ? (fcs >> 1) ^ 0x8408 : (fcs >> 1);
byte = byte >> 1;
}
return fcs;
}
Am I doing something wrong? If I send 0xFF, or 0x00 I do not get the same checksum as I do on http://depa.usst.edu.cn/chenjq/www2/SDesign/JavaScript/CRCcalculation.htm
printf("%04X\n", crc16(0x31, 0xFFFF)); //returns 2F8D
I have read your questions and I also had the similar problem like you.
I have solved this issue for calculating CRC-CCITT in XMODEM. here I am attaching the sample program to calculate CRC-CCITT.
I have tried the data with the online converter and this program. Please use this if you wish.
unsigned short crc16(char *ptr, int count)
{
int crc;
char i;
crc = 0;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
CRC should be defined as unsigned short since the crc16 function returns an unsigned short. CRC is defined as an int which on most systems is 4 bytes.
Take a look at Greg Cook's excellent catalog of CRCs. There is a variant often falsely identified as the CCITT CRC, which it isn't. That is what your code, with the 0xFFFF initialization, appears to be computing, though reflected. The Kermit CRC is the actual CCITT CRC. To get the CCITT CRC, you should start with zero, not 0xFFFF. The XMODEM CRC is different still, like the Kermit CRC, but unreflected (so bits go in the top, and you exclusive-or with 0x1021).
KERMIT
width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"
XMODEM
width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3 name="XMODEM"
CRC-16/CCITT-FALSE
width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 name="CRC-16/CCITT-FALSE"
static const unsigned short CRC_CCITT_TABLE[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
I use the following code to calculate a CRC-CCITT (0xFFFF):
unsigned short Calculate_CRC_CCITT(const unsigned char* buffer, int size)
{
unsigned short tmp;
unsigned short crc = 0xffff;
for (int i=0; i < size ; i++)
{
tmp = (crc >> 8) ^ buffer[i];
crc = (crc << 8) ^ CRC_CCITT_TABLE[tmp];
}
return crc;
}
For Java
Install: https://mvnrepository.com/artifact/com.github.snksoft/crc/1.0.2
Long returnValue = CRC.calculateCRC(Parameters.CCITT, "yourStringValue");
In my application, I record audio data from an ASIO driver:
void newData(void *buffer, int length)
where buffer is the buffer pointer and length is the number of samples in that buffer. In my case, I know that the samples are 4-byte integers and the buffer contains 1024 samples every run.
Now, I save these samples in two ways: little-endian binary (to be later used as a WAV file) and a text file. The text file saving words good, I get the numbers and they correspond to the samples form the waveform. But the binary file will always contain a little good data and the rest is just mangled.
Original data (original sound and text saving):
Mangled data (binary saving):
The code (I use std::ofstream):
//binary saving
tempOut.write((char *)buffer, length * 4);
//text saving
int *intBuf = (int *)buffer;
for(int i = 0; i < length; i++){
textOut << intBuf[i];
textOut << '\n';
}
Note that the problem is not with synchronization, as I save the binary data first and the text data second.
How the data are mangled:
Original binary (LE) binary (BE) binary to dec
206016 C0240300 000324C0 206016
815616 00720C00 000C7200 815616
1804032 00871B00 001B8700 1804032
3131392 00C82F00 002FC800 3131392
4741440 40594800 00485940 4741440
6567552 80366400 00643680 6567552
8531264 402D8200 00822D40 8531264
10545664 00EAA000 00A0EA00 10545664
12517632 0001BF00 00BF0100 12517632
14353920 0006DB00 00DB0600 14353920
15958976 C083F300 00F383C0 15958976
17241600 00160701 01071600 17241600
18119296 807A1401 01147A80 18119296
18514048 80801A01 011A8080 18514048
18365760 403D1801 01183D40 18365760
17622016 00E40C01 010CE400 17622016
16253632 C002F800 00F802C0 16253632
14246784 8063D900 00D96380 14246784
11605504 0016B100 00B11600 11605504
8355840 00807F00 007F8000 8355840
4541376 C04B4500 00454BC0 4541376
228096 007B0300 00037B00 228096
-4501376 8050BBFF FFBB5080 4290465920
-9549312 004A6EFF FF6E4A00 4285417984
-14798400 C0311EFF FF1E31C0 4280168896
-20126080 80E6CCFE FECCE680 4274841216
-25391232 808F7CFE FE7C8F80 4269576064
-30458624 003D2FFE FE2F3D00 4264508672
-35178624 8037E7FD FDE73780 4259788672
-39413760 0098A6FD FDA69800 4255553536
-43025024 807D6FFD FD6F7D80 4251942272
-45883392 00E043FD FD43E000 4249083904
-47872704 408525FD FD258540 4247094592
-48899072 00DC15FD FD15DC00 4246068224
-48881280 802116FD FD162180 4246086016
-47759616 003F27FD FD273F00 4247207680
-45503488 00AC49FD FD49AC00 4249463808
-42107648 007D7DFD FD7D7D00 4252859648
-37589760 006DC2FD FDC26D00 4257377536
-32005120 00A417FE FE17A400 4262962176
-25429184 40FB7BFE FE7BFB40 4269538112
-17961216 00EFEDFE FEEDEF00 4277006080
-9736576 806E6BFF FF6B6E80 4285230720
-909568 001FF2FF FFF21F00 4294057728
8349120 C0657F00 007F65C0 8349120
17843584 80451001 01104580 17843584
27378816 80C4A101 01A1C480 27378816
36731904 007C3002 02307C00 36731904
45697792 004BB902 02B94B00 45697792
54044800 80A83803 0338A880 54044800
61575360 C090AB03 03AB90C0 61575360
68087552 00EF0E04 040EEF00 68087552
73396096 80EF5F04 045FEF80 73396096
77338368 00179C04 049C1700 77338368
79784320 8069C104 04C16980 79784320
80611328 0008CE04 04CE0800 80611328
79763520 4018C104 04C11840 79763520
77187328 00C99904 0499C900 77187328
72884352 80205804 04582080 72884352
66885120 0096FC03 03FC9600 66885120
59262720 00478803 03884700 59262720
50139648 0012FD02 02FD1200 50139648
39658752 00255D02 025D2500 39658752
28000256 0040AB01 01AB4000 28000256
15379520 40ACEA00 00EAAC40 15379520
2044416 00321F00 001F3200 2044416
-11740544 80DA4CFF FF4CDA80 4283226752
-25707264 00BD77FE FE77BD00 4269260032
-39540864 80A7A4FD FDA4A780 4255426432
-52953600 00FED7FC FCD7FE00 4242013696
-65651712 003C16FC FC163C00 4229315584
-77331456 000464FB FB640400 4217635840
-87716800 408CC5FA FAC58C40 4207250496
-96567040 00813EFA FA3E8100 4198400256
-103632000 80B3D2F9 F9D2B380 4191335296
-108724992 00FD84F9 F984FD00 4186242304
-111678336 80EC57F9 F957EC80 4183288960
-112379904 00384DF9 F94D3800 4182587392
-110761792 C0E865F9 F965E8C0 4184205504
-106792960 0078A2F9 F9A27800 4188174336
-100491840 C09D02FA FA029DC0 4194475456
-91944960 000885FA FA850800 4203022336
-81278912 40C827FB FB27C840 4213688384
-68651520 0076E8FB FBE87600 4226315776
-54296640 C07FC3FC FCC37FC0 4240670656
-38472960 00F3B4FD FDB4F300 4256494336
-21475776 404EB8FE FEB84E40 4273491520
-3638272 007CC8FF FFC87C00 4291329024
14684288 8010E000 00E01080 14684288
33120000 005FF901 01F95F00 33120000
51280320 C0790E03 030E79C0 51280320
68789504 00A51904 0419A500 68789504
85244544 80BA1405 0514BA80 85244544
100304768 8087FA05 05FA8780 100304768
113604800 C078C506 06C578C0 113604800
124833792 00D07007 0770D000 124833792
133720320 0069F807 07F86900 133720320
140022400 80925808 08589280 140022400
143561088 80918E08 088E9180 143561088
144198400 004B9808 08984B00 144198400
141871872 00CB7408 0874CB00 141871872
136572288 80ED2308 0823ED80 136572288
128333056 0035A607 07A63500 128333056
117298688 00D6FD06 06FDD600 117298688
103608960 80F22C06 062CF280 103608960
87533952 80A93705 0537A980 87533952
69342848 80162204 04221680 69342848
49372416 005DF102 02F15D00 49372416
28008640 C060AB01 01AB60C0 28008640
5674240 00955600 00569500 5674240
-17177472 80E4F9FE FEF9E480 4277789824
-40097792 00289CFD FD9C2800 4254869504
-62600192 00CC44FC FC44CC00 4232367104
-84225024 00D4FAFA FAFAD400 4210742272
-104489920 409CC5F9 F9C59C40 4190477376
-122963712 00B9ABF8 F8ABB900 4172003584
-139224384 C09AB3F7 F7B39AC0 4155742912
-152897792 00F7E2F6 F6E2F700 4142069504
-163660224 40BE3EF6 F63EBE40 4131307072
-171233280 0030CBF5 F5CB3000 4123734016
-175417088 00598BF5 F58B5900 4119550208
-176054784 009E81F5 F5819E00 4118912512
-173089536 00DDAEF5 F5AEDD00 4121877760
-166513152 003613F6 F6133600 4128454144
-156400000 8086ADF6 F6AD8680 4138567296
-142918272 803D7BF7 F77B3D80 4152049024
-126284736 400C79F8 F8790C40 4168682560
-106782720 00A0A2F9 F9A2A000 4188184576
-84789120 8038F2FA FAF23880 4210178176
-60711040 809F61FC FC619F80 4234256256
-35003200 C0E4E9FD FDE9E4C0 4259964096
-8186112 001783FF FF831700 4286781184
19211584 40252501 01252540 19211584
46627712 807BC702 02C77B80 46627712
73500480 40876104 04618740 73500480
99269120 00BAEA05 05EABA00 99269120
123365760 80695A07 075A6980 123365760
145304064 002AA908 08A92A00 145304064
164576000 003BCF09 09CF3B00 164576000
Here the mangling occurs:
180750080 0007C60D 0DC60700 231081728
193447488 0A40C687 87C6400A 2277916682
202362496 0B80CE0F 0FCE800B 265191435
207247040 0CC0565A 5A56C00C 1515634700
207959040 0C003465 6534000C 1697906700
204410560 0CC00E2F 2F0EC00C 789495820
196625792 0C8045B8 B845800C 3091562508
184697856 0B004402 0244000B 38010891
168819456 0B00FB0F 0FFB000B 268107787
149276544 0D0A80C7 C7800A0D 3347057165
126403200 E50880C2 C28008E5 3263170789
100631232 8807C082 82C00788 2193622920
72473600 FF0500DC DC0005FF 3690989055
42428736 51044069 69400451 1765803089
11137280 870200F1 F1000287 4043309703
-20792320 A90000BC BC0000A9 3154116777
-52715520 C2FE00A0 A000FEC2 2684419778
-83981184 DBFC808C 8C80FCDB 2357263579
-113911680 FEFA80D8 D880FAFE 3632331518
-141894144 35F900DE DE00F935 3724605749
-167331840 8AF700B8 B800F78A 3087071114
-189665728 06F640EE EE40F606 3997234694
-208386432 B1F48046 4680F4B1 1182856369
-223077888 94F3001A 1A00F394 436269972
-233389056 B4F200C4 C400F2B4 3288396468
-239046720 16F2C06F 6FC0F216 1874915862
-239889920 C0F10092 9200F1C0 2449535424
-235830720 B3F14082 8240F1B3 2185294259
-226899456 F1F100CA CA00F1F1 3389059569
-213204992 79F200C0 C000F279 3221287545
-195002240 4AF38080 8080F34A 2155934538
-172597824 60F4C05D 5DC0F460 1572926560
-146384384 B6F5005A 5A00F5B6 1510012342
-116876032 46F7009D 9D00F746 2634086214
-84644736 08F9806C 6C80F908 1820391688
-50310400 F4FA0053 5300FAF4 1392573172
You can see how the wave is represented, positive and negative values alternate, until certain point. Then it becomes rubbish.
You forgot to open the output file for binary data in binary mode. Therefore every time a byte 0x0A is sent to output the file receives (in a windows system) 0x0D 0x0A.
If I'm interpreting your first line of information on the data correctly:
Original binary (LE) binary (BE) binary to dec
206016 C0240300 000324C0 206016
Then the correct value is the big-endian data. If what you are seeing on disk is the 0xC0240300, then you are working on a little-endian machine (an Intel CPU), and you need to write the data in a big-endian format (and read it back in big-endian format too).
The way you're currently doing it is:
//binary saving
tempOut.write((char *)buffer, length * 4);
I assume 'buffer' is an array of 4-byte integers (in my work, it would most commonly be an array of char, but then the cast would be irrelevant).
I think that one way to do it 'better' might be:
enum { MAX_SAMPLES = 1024 };
char binbuff[4 * MAX_SAMPLES];
assert(length <= MAX_SAMPLES);
char *dst = binbuff;
for (int i = 0; i < length; i++)
{
*dst++ = (buffer[i] >> 24) & 0xFF;
*dst++ = (buffer[i] >> 16) & 0xFF;
*dst++ = (buffer[i] >> 8) & 0xFF;
*dst++ = (buffer[i] >> 0) & 0xFF;
}
tempOut.write(binbuff, 4 * length);
There are multiple more or less equivalent mechanisms available to achieve the same result.
Reading would be the inverse operation. You'd read the data into a character (byte) array, and then assemble each four bytes into a value:
int sample[MAX_SAMPLES];
char binbuff[4 * MAX_SAMPLES];
tempIn.read(binbuff, sizeof(binbuff));
char *src = binbuff;
for (int i = 0; i < MAX_SAMPLES; i++, src += 4)
{
sample[i] = (src[0] & 0xFF) << 24 |
(src[1] & 0xFF) << 16 |
(src[2] & 0xFF) << 8 |
(src[3] & 0xFF) << 0;
}
The optimizer will remove the shifts by zero; they make the symmetry of the operations clear in the source code.