Python CRC32 Reverse Hash e8b7be43 to string “a”

I am trying to reverse a hash into a sequence of bytes. The function is shown below.

def decrypt(hash, size):
    bytes = bin(int(hash, 16)).replace("0b", "").zfill(32)
    bytes = flip(reverse(int(bytes, 2), 32), 33)
    div = "100000100110000010001110110110111"
    bytes = bytes.zfill(size*8)
    div = div.zfill(size*8)
    res = ""
    print(bytes + " - DIV")
    print(div + " - POLY")
    while div[0] != "1":
        res = ""
        for b in range(len(bytes)):
            if div[b] == bytes[b]:
                res = res + "0"
            else:
                res = res + "1"
        bytes = bin(int(res, 2) << 1).replace("0b", "").zfill(size*8)
        div = bin(int(div, 2) << 1).replace("0b", "").zfill(size*8)
        print(bytes + " - DIV")
        print(div + " - POLY")
    print(bytes)
    bytes = flip(bytes[0:8], 8) + flip(bytes[8:16], 8) + flip(bytes[16:24], 8) + flip(bytes[24:32], 8) + bytes[32:len(bytes)]
    bytes = bytes[0:len(bytes)-32]
    bytes = [int(reverse(int(bytes[(c*8):(c+1)*8], 2), 8), 2) for c in range(int(len(bytes)/8))]
    print(hex(zlib.crc32(bytearray(bytes))))
    return bytes
print(decrypt(sys.argv[1], int(sys.argv[2])+4))

And here is the output.

>>>python encrypt.py a
40
0xe8b7be43
[97]

>>>python decrypt.py e8b7be43 1
0000000000111101100000100001001011101000 - DIV
0000000100000100110000010001110110110111 - POLY
0000001001110010100001100001111010111110 - DIV
0000001000001001100000100011101101101110 - POLY
0000000011110110000010000100101110100000 - DIV
0000010000010011000001000111011011011100 - POLY
0000100111001010000110000111101011111000 - DIV
0000100000100110000010001110110110111000 - POLY
0000001111011000001000010010111010000000 - DIV
0001000001001100000100011101101101110000 - POLY
0010011100101000011000011110101111100000 - DIV
0010000010011000001000111011011011100000 - POLY
0000111101100000100001001011101000000000 - DIV
0100000100110000010001110110110111000000 - POLY
1001110010100001100001111010111110000000 - DIV
1000001001100000100011101101101110000000 - POLY
1001110010100001100001111010111110000000
0xa0058808
[198]

The issue here is that the hash of the bytearray that the “decrypt” function generates does not match the input hash e8b7be43. How do I fix this?

6

Here is an example in C of reversing a CRC-32 value to produce the four-byte message and any shorter messages that have that CRC:

// Reverse a CRC-32 into the unique four-byte and any shorter sequences that
// have that CRC. This is implemented for the standard ISO-HDLC / zlib CRC-32.
//
// Placed into the public domain by Mark Adler, 19 Dec 2024.

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

#define POLYROT 0xdb710641      // Reflected CRC polynomial rotated left one

// Get a CRC-32 from the command line and show the four-byte plus any shorter
// sequences that give that CRC-32. The CRC can be provided in hexadecimal by
// preceding it with "0x". The results are shown in hexadecimal.
int main(int argc, char **argv) {
    if (argc != 2) {
        fputs("Usage: crcseqs 0x352441c2n", stderr);
        return 1;
    }
    uint32_t crc = strtoul(argv[1], NULL, 0);
    if (crc == 0)
        // The zero-byte sequence has a CRC-32 of zero.
        puts("<empty sequence>");
    crc = ~crc;
    for (int n = 1; n <= 4; n++) {
        // See if there is an n-byte sequence with that CRC-32.
        for (int k = 0; k < 8; k++)
            crc = crc & 0x80000000 ? (crc << 1) ^ POLYROT : crc << 1;
        if (n == 4 || (~crc >> (n << 3)) == 0)
            // Yes, there is.
            for (int i = 0; i < n; i++)
                printf("%02x%c", (~crc >> (i << 3)) & 0xff,
                       i < n - 1 ? ' ' : 'n');
    }
    return 0;
}

The statement in the inner for loop runs the CRC backwards over one zero bit. It simply undoes what this corresponding statement does for a usual reflected CRC, where for the standard CRC-32 used here, POLY is 0xedb88320:

    crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;

The inner for loop does that eight times to run the CRC backwards over one zero byte.

We will consider the n == 4 case, where that loop has been run four times to process four zero bytes backwards, determining the initial CRC required to get the given CRC when run over a message of four zero bytes.

CRCs are linear over GF(2). That means that if we take two CRC calculations, each with an initial CRC, the message bytes, and a final CRC, we can exclusive-or those together and get a new initial CRC, message bytes, and final CRC that represent a correct CRC calculation, without having to have done that calculation.

Consider what happens if we take the initial CRC that we calculated for n == 4, and then run a CRC calculation over that CRC as the message bytes. (For this to work for a reflected CRC, we need to process the CRC bytes in little-endian order.) The usual CRC calculation for one byte, let’s call it octet, is:

    crc ^= octet;
    for (int k = 0; k < 8; k++)
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;

For the first byte, that ^= exclusive-ors the low byte of the CRC with the low byte of the CRC, giving zero in the low byte. Then the for loop will see eight zero bits, and so simply shift the CRC right eight bits. This repeats for the next three bytes, getting zero in the low byte each time, resulting in a final CRC of zero.

We now have an initial CRC that is what we calculated backwards given a four-zeros message, a four-byte message consisting of that CRC in little-endian order, and a final CRC of zero. We now exclusive-or those three with the other calculated message with the same initial CRC, a message of four zero bytes, and the desired final CRC. We get a new triplet with a zero initial CRC, a four-byte message which is the computed initial CRC in little-endian order, and the desired final CRC, since we exclusive-or’ed that one with zero.

And there we have it! Those four bytes with an initial CRC of zero give the desired final CRC that was provided on the command line.

All of the explanation above assumes that the CRC definition has an initial value of zero and final exclusive-or of zero, i.e. no exclusive-or. However the standard CRC-32 here has an initial value of 0xffffffff and a final exclusive-or of 0xffffffff. The ~‘s in the code take care of that.

I will leave it to the reader as an exercise to determine how this works for n == 1, 2, and 3.

2

Please understand that “to hash” is quite different from “to encrypt”.
Yes, one can
build
a cipher from secure hashes.
But that’s not what is going on here, and crc32 is in no way a
secure hash,
quite aside from the fact that a security parameter of 32 bits is easily bruted.

A hash is a one-way function, which might have several competing design considerations such as “small”, “fast”, “cryptographically secure”.
It reduces a large number of bits down to a fixed number such as 512 or 32.

A symmetric cipher turns N bits of cleartext into ~ N bits of ciphertext,
with the possibility to go back and forth,
via decrypt and encrypt routines.
This is not at all like a hash that turns a million bits of input
into a small fixed size output.

How do I fix this?

Read Crypto Eng.
or a similar reference, and rethink your approach to the business problem.
You want to bring relevant cryptographic primitives to bear upon it.

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật