0

I have a very weird use case. Tl;dr I'm trying to convert a bytes16 to a base 10 integer by keeping the digits in tact.

i.e 0x00000000000000000000000002987391 should become 2987391

1 Answer 1

1

Assuming all the hex numbers are between 0-9, you can use one of the two functions below (the first one is more gas efficient, while the second function is more human readable). The output can be reduced to uint112 if needed since the max number is 0x99999999999999999999999999999999.

function hex2Base10Assembly (bytes16 input) public pure returns (uint output) {
    
    uint power10 = 1;

    assembly {
        input := shr(128, input)
        for { let i := 0 } lt(i, 31) { i := add(i, 1) } {
            output := add(output, mul(mod(input, 16), power10)) 
            input := div(input, 16)
            power10 := mul(power10, 10)
        }             
        output := add(output, mul(mod(input, 16), power10))   
    }
    return output;
}

Human readable:

function hex2Base10 (bytes16 hexInput) public pure returns (uint output) {

    uint power10 = 1;

    uint128 input = uint128(hexInput);

    for(uint i; i < 31; ++i) {
        output = output + (input % 16) * power10;
        input = input / 16;
        power10 = power10 * 10;
    }

    output = output + (input % 16) * power10;

    return output;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.