# Compare last 2 digits of block hash

I am having trouble doing some string comparison against the last 2 digits of a block hash in solidity. I'm also a little bit confused about how to work with a single character, as it appears that a single byte in solidity contains 2 characters.

I grab a blockhash:

``````bytes32 myHash = block.blockhash(block.number - 1);
``````

And I get something like:

"0x18676e992055c057538d59b378271bb4eacdb7f6abf9e815fd63255dc11166b6"

I attempt to grab the last character by doing:

``````byte x = myHash;
``````

This gives me a value like this, when printed in a log:

"b600000000000000000000000000000000000000000000000000000000000000"

This is where I'm confused. This is the last 2 characters of the bytes32. I want to use the following function to determine the hex integer value of the character:

``````function getCoordinate(byte val) returns(uint) {
if (val == "0") {
return 0;
} else if (val == "1") {
return 1;
} else if (val == "2") {
return 2;
} else if (val == "3") {
return 3;
} else if (val == "4") {
return 4;
} else if (val == "5") {
return 5;
} else if (val == "6") {
return 6;
} else if (val == "7") {
return 7;
} else if (val == "8") {
return 8;
} else if (val == "9") {
return 9;
} else if (val == "a") {
return 10;
} else if (val == "b") {
return 11;
} else if (val == "c") {
return 12;
} else if (val == "d") {
return 13;
} else if (val == "e") {
return 14;
} else if (val == "f") {
return 15;
}
}
``````

However, none of the cases match, so it always returns 0. Anyone have any knowledge of how to get a single character so that this function will work properly?

• What do you mean by hex integer value? Are you saying you want to convert the last byte in the hash to its integer value? – jojeyh Oct 26 '17 at 3:32
• Yeah exactly, I worded that poorly. I want to get from the hexadecimal character in the bytes32 to an integer value (between 1 and 16) – John Palmer Oct 26 '17 at 3:37

Since every byte is encoded as 2 hexadecimal characters (e.g. in your example the last byte is 0xb6) you need 2 functions: one for the left coordinate, another for the right coordinate:

``````function getRightCoordinate(byte input) returns(uint) {
byte val = input & byte(15);
return uint(val);
}

function getLeftCoordinate(byte input) returns(uint) {
byte val = input >> 4;
return uint(val);
}
``````

`15` is the decimal representation of the binary 00001111. Bitwise `&` with it gives you the right coordinate.

`>> 4` shifts the first 4 bits to the right discarding the other 4 bits.

• Thanks, this is exactly what I was looking for, and it's more efficient than the answer I posted. Accepting this answer. – John Palmer Oct 27 '17 at 3:58

Bytes have 8 bits, so a single byte will contain up to 256 (2*2*2*2*2*2*2*2) values. A hex character is 16 values (10 digits + 6 letters), so you use 2 hex characters when you represent a byte (16*16 = 256).

`bytes32` data types can be seamlessly converted into a number of type `uint256` (32 8-bit bytes makes 256 bits), so the obvious thing to do is just turn the block hash into a number, divide it by 16 and take the remainder. The following (untested) code should give you a number from 0 to 15:

`uint256 your_num = uint256(block.blockhash(block.number - 1)) % 16;`

• Awesome! Going to try this as soon as I am back at my computer. Will follow up here after. – John Palmer Oct 26 '17 at 6:07
• I guess I misread this earlier because this won't quite work for me. I need to get an integer 1-16 specifically from the last digit of the blockhash. I can't use all of the characters. The reason is that I will need to do this for another character as well. e.g. Last characters are "0a" then the 2 numbers are 0 and 10. – John Palmer Oct 26 '17 at 15:39

I was able to use Edmund's hint of working with uint256 to find a solution to my problem. By some creative bit shifting, you can get the integer value of a single digit. In my case, I wanted the last 2 digits of the blockhash.

``````bytes32 myHash = block.blockhash(block.number - 1);
uint256 hashNum = uint256(myHash);

// Last Character alone
// Shift left by 252 bits (leaving just 4 bits left), then shift back to the right
uint256 last = (hashNum * 2 ** 252) / (2 ** 252);

// Second to last character alone
// Shift left by 248 bits (leaving 8 bits left), but then shift right by 252
uint256 secondLast = (hashNum * 2 ** 248) / (2 ** 252);
``````

So there you have it, the final 2 characters of the blockhash as integers between 0 - 15.

There is a more optimal solution using bit masking instead of shifting. I will post it here later if I get it working.