I want to find the substring (index 0 to 13) of bytes32 data and convert it into uint256 data

Viewed 1188

I am stuck in solidity code. I want substring of below data and convert it to uint256 data

bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;

I want first 13 chars of above hmacSha256 data i.e. 'f83bf40815929' and its uint256 ie. 4366982094870825. I tried a number of things but to failure. Code and tried code is below:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Storage
 * @dev Store & retrieve value in a variable
 */
contract TestContract {
    
        
    function getsubstring1() public pure returns (string memory, uint256, string memory) {
        bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;
        bytes memory tempH = bytes(abi.encodePacked(hmacSha256));
        uint256 uintHash = uint256(hmacSha256);
        
        //I want below values as result. 
        // _hs is first 13 chars of hmacSha256.
        //neither i could derive the _hs and nor _h from _hs.
        string memory _hs = '0xf83bf40815929'; 
        uint256 _h = 0xf83bf40815929;
        
        //What I tried
        //bytes13 _hs1 = bytes13(hmacSha256); 
        //but its returning 0xf83bf40815929b2448b230d51f which is double the length of expected value 0xf83bf40815929
        
        //string memory _hs1 = substring(string(abi.encodePacked(hmacSha256)), 0, 13); 
        //above code is throwing error:Failed to decode output: null: invalid codepoint at offset 0; bad codepoint prefix
        
        // bytes memory _hs2 = tempH[0:13] ;
        //above giving error that its for bytes calldata dynamic array

        //uint256 _h1 = uint256(bytes(abi.encodePacked(_hs)));
        
        return (_hs, _h, _hs1);
    }
    
    function substring(string memory str, uint startIndex, uint endIndex) public pure returns (string memory) {
        bytes memory strBytes = bytes(str);
        bytes memory result = new bytes(endIndex-startIndex);
        for(uint i = startIndex; i < endIndex; i++) {
            result[i-startIndex] = strBytes[i];
        }
        return string(result);
    }
}
1 Answers

You need to perform few typecasts and bitwise operatations, see the code comments.

Code:

pragma solidity ^0.8;

contract TestContract {
    
    function getsubstring() external pure returns (bytes7, uint256) {
        bytes32 hmacSha256 = 0xf83bf40815929b2448b230d51fa2eaa5b8ccffd87691db7e62bf817b2cbb56ad;

        bytes7 first7Bytes = bytes7(hmacSha256); // get the first 7 bytes (14 hex characters): 0xf83bf40815929b
        bytes7 thirteenHexCharacters = first7Bytes >> 4; // move 4 bytes (1 hex character) to the right: 0x0f83bf40815929

        bytes32 castBytes = bytes32(thirteenHexCharacters); // cast the bytes7 to bytes32 so that we can cast it to integer later
        bytes32 castBytesMoved = castBytes >> 200; // move 200 bytes (50 hex characters) to the right: 0x000000000000000000000000000000000000000000000000000f83bf40815929
        uint256 integerValue = uint256(castBytesMoved); // cast the bytes32 to uint256

        return (thirteenHexCharacters, integerValue);
    }
}

Returned values:

bytes7: 0x0f83bf40815929
uint256: 4366982094870825
Related