Post
Topic
Board Bitcoin Technical Support
Topic OP
Satoshi Compact Varint - CVARINT
by
dr10101
on 31/01/2024, 10:34:27 UTC
Hello, my transformation needs to be precisely reversible. The Satoshi compact CVarint (not Varint) was used.
Here is my Python interpretation, but it seems to have created characters outside the ascii range so I can't verify.

serialize.h of the period doesn't address this fully, appreciate any pointers, artifacts ??

def encode_camount(amount):
    # CAmount transformation
    if amount == 0:
        transformed_value = 0
    else:
        e = 0
        while amount % 10 == 0 and e < 9:
            amount //= 10
            e += 1
        if e < 9:
            d = amount % 10
            n = amount // 10
            transformed_value = 1 + 10 * (9 * n + d - 1) + e
        else:
            transformed_value = 1 + 10 * (amount - 1) + 9

    # MSB base-128 encoding
    encoded_bytes = []
    while transformed_value > 0:
        byte = transformed_value & 0x7F
        transformed_value >>= 7
        if transformed_value > 0:
            byte |= 0x80
            byte -= 1
        encoded_bytes.insert(0, byte)

    return encoded_bytes

def decode_camount(encoded_bytes):
    # Decode the variable-length integer
    decoded_value = 0
    for i, byte in enumerate(reversed(encoded_bytes)):
        if i > 0:
            decoded_value += (byte + 1) * (128 ** i)
        else:
            decoded_value += byte

    # Reverse the CAmount transformation
    if decoded_value == 0:
        return 0
    e = decoded_value % 10
    decoded_value = (decoded_value - 1) // 10
    if e < 9:
        n = decoded_value // 9
        d = decoded_value % 9 + 1
        original_amount = n * 10 + d
    else:
        original_amount = decoded_value + 1
    original_amount *= 10 ** e

    return original_amount


input_string = "<provided if you can help>"



# Step 1: Encoding - Convert each character to a byte and encode
encoded_data = [encode_camount(ord(c)) for c in input_string]
print("Encoded Data:", encoded_data)

# Step 2: Decoding - Decode each byte sequence
decoded_bytes = [decode_camount(data) for data in encoded_data]
print("Decoded Bytes:", decoded_bytes)

# Step 3: Re-encoding - Re-encode the decoded bytes
reencoded_data = [encode_camount(b) for b in decoded_bytes]
print("Reencoded Data:", reencoded_data)

# Step 4: Convert reencoded data back to byte literals
reencoded_bytes = bytearray()
for data in reencoded_data:
    for byte in data:
        reencoded_bytes.append(byte)

# Convert bytearray to string for display
reencoded_string = ''.join(format(x, '02x') for x in reencoded_bytes)
print("Reencoded Byte String:", reencoded_string)

# Step 5: Verification
verification = ''.join(format(ord(c), '02x') for c in input_string) == reencoded_string
print("Verification Successful:", verification)

Thx for any pointers outside a google search....