Код: Выделить всё
('Hello blah https://www.google.com', 2708940679),
('Blah https://google.com https://yahoo.com', 4040448680),
('Blah https://yahoo.com', 3819201094),
('Blah https://Cnn.com', 2989447761),
('https://cnn.com', 4131379772)]
Упомянутый алгоритм затем ссылается на другой алгоритм для создания кэша. Вот генератор кэша:
Код: Выделить всё
IF Called once
RETURN
END IF
FOR each Index from 0 to 255
SET Value to Index
SHIFT Value left by 24 bits
FOR Bit from 0 to 7
IF highest (31st) bit of Value is set
SHIFT Value left by 1 bit
Bitwise exclusive-OR Value with xAF
ELSE
SHIFT Value left by 1 bit
END IF
END FOR
AND Value with 0xFFFF
SET Cache[Index] to Value
END LOOP
END SUBROUTINE
Код: Выделить всё
SUBROUTINE CRC(CrcValue, Array)
CALL InitCrcCache()
FOR each Byte from Array
SET Index to CrcValue
SHIFT Index right 24 bits
Bitwise exclusive-OR Index with Byte
SHIFT CrcValue left 8 bits
Bitwise exclusive-OR CrcValue with Cache[Index]
END LOOP
RETURN CrcValue
END SUBROUTINE
Генератор кэша
Код: Выделить всё
def init_crc_cache():
"""
Implements SUBROUTINE InitCrcCache() using fixed-width uint32.
"""
# Create an array of 256 uint32s
cache = np.zeros(256, dtype=np.uint32)
poly = np.uint32(0x000000AF)
# Constants for shifts and comparisons
one = np.uint32(1)
twenty_four = np.uint32(24)
msb_mask = np.uint32(0x80000000)
for i in range(256):
# SET Value to Index SHIFT Value left 24 bits
value = np.left_shift(np.uint32(i), twenty_four)
for _ in range(8):
# Check if the highest bit is set
if np.bitwise_and(value, msb_mask) != 0:
# SHIFT Value left 1 bit then XOR with Poly
value = np.bitwise_xor(np.left_shift(value, one), poly)
else:
# SHIFT Value left 1 bit
value = np.left_shift(value, one)
value = value & 0xFFFF
cache[i] = value
return cache
CACHE = init_crc_cache()
Код: Выделить всё
def mso_crc32_compute(data_bytes_or_str: bytes|str, initial_crc: int = 0) -> int:
"""
Implements SUBROUTINE CRC(CrcValue, Array) from MS-OSHARED 2.4.3.2.
"""
if isinstance(data_bytes_or_str, str):
data_bytes = data_bytes_or_str.encode("utf8")
else:
data_bytes = data_bytes_or_str
# Cast initial value to uint32
crc_value = np.uint32(initial_crc)
# Fixed shift constants
twenty_four = np.uint32(24)
eight = np.uint32(8)
for byte in data_bytes:
assert isinstance(byte, int)
# SET Index to CrcValue SHIFT Index right 24 bits
# Index = (crc_value >> 24) ^ byte
# Note: we cast byte to uint32 to match types for bitwise_xor
index_val = np.bitwise_xor(
np.right_shift(crc_value, twenty_four), np.uint32(byte)
)
# Ensure index is 0-255
index = int(np.bitwise_and(index_val, np.uint32(0xFF)))
# SHIFT CrcValue left 8 bits XORed with Cache[Index]
crc_value = np.bitwise_xor(np.left_shift(crc_value, eight), CACHE[index])
# Return as standard Python int for ease of use (e.g. hex formatting)
return int(crc_value)
Код: Выделить всё
for txt, expect in pairs:
print(f"{expect} | {mso_crc32_compute(txt)}")
4095518050 | 3261000321
2708940679 | 401344468
4040448680 | 3621410886
3819201094 | 195308597
2989447761 | 3212963651
4131379772 | 1224667129
Подробнее здесь: https://stackoverflow.com/questions/798 ... -extension
Мобильная версия