okdshin/PicoSHA2

Hash calculates differently when reading from binary file

WilliamVenner opened this issue · 3 comments

Here is my rough code:

// Write to file
// Works ok

uint64_t me = 76561198040894045;

std::string str_to_hash = "test";
std::vector<unsigned char> s(picosha2::k_digest_size);
picosha2::hash256(str_to_hash.begin(), str_to_hash.end(), s);

std::ofstream odt;
odt.open("test.txt", std::ios::out | std::ios::binary);

// Write uint64_t using two uint32_t
uint32_t hval = htonl((me >> 32) & 0xFFFFFFFF);
uint32_t lval = htonl(me & 0xFFFFFFFF);
odt.write((const char*)&hval, sizeof(hval));
odt.write((const char*)&lval, sizeof(lval));

for (unsigned int i = 0; i < s.size(); i++) {
	odt.write((const char*)&s.at(i), sizeof(s.at(i)));
}

odt.flush();
odt.close();
// Read from file
// Doesn't work

std::ifstream idt("test.txt", std::ios::in | std::ios::binary);
if (idt.is_open() && !idt.fail()) {
	uint64_t steamid64;
	while (idt) {
		uint32_t val[2] = { 0 };
		if (idt.read((char*)val, sizeof(val)))
		{
			steamid64 = (uint64_t)ntohl(val[0]) << 32 | (uint64_t)ntohl(val[1]);
		}

		std::vector<unsigned char> s(picosha2::k_digest_size);
		picosha2::hash256(idt, s.begin(), s.end());

		if (idt.eof()) break;

		std::string hash_hex_str;
		picosha2::bytes_to_hex_string(s.begin(), s.end(), hash_hex_str);

		std::cout << hash_hex_str;
	}

	idt.close();
}

Output:

954d5a49fd70d9b8bcdb35d252267829957f7ef7fa6c74f88419bdc5e82209f4

test SHA256:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08


I can get it to work by reading manually into the vector:

// Read from file
// Works ok

std::ifstream idt("test.txt", std::ios::in | std::ios::binary);
if (idt.is_open() && !idt.fail()) {
	uint64_t steamid64;
	while (idt) {
		uint32_t val[2] = { 0 };
		if (idt.read((char*)val, sizeof(val)))
		{
			steamid64 = (uint64_t)ntohl(val[0]) << 32 | (uint64_t)ntohl(val[1]);
		}

		std::vector<unsigned char> s(picosha2::k_digest_size);
		for (unsigned int i = 0; i < 32; i++) {
			uint8_t blah;
			idt.read((char*)&blah, sizeof(blah));
			s.at(i) = blah;
		}
		//picosha2::hash256(idt, s.begin(), s.end());

		if (idt.eof()) break;

		std::string hash_hex_str;
		picosha2::bytes_to_hex_string(s.begin(), s.end(), hash_hex_str);

		std::cout << hash_hex_str;
	}

	idt.close();
}

Output:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Building on Win32 using Haswell Intel Core i7 4790K

@WilliamVenner Sorry for my late reply.
The line in your "Read from file" code;
picosha2::hash256(idt, s.begin(), s.end());
means "hashing the hashed data". So the printed hex string is different.

oh, my apologies. I think I copied that code from the documentation though, or another similar issue.