Solidity – How to Change the 5th and 6th Byte from bytes8

bytesbytes32solidity

Hi Guys ,
How can i change the 5th and 6th byte from this bytes8 0x3FcB875f"0000"ddC4,or just arrive at this solution where:
last four bytes(of bytes8) are this way 0x********"0000ddC4" and the first four bytes(of bytes8) can have any number but !=0 ?

bytes8 normal=0x3FcB875f56beddC4
// POSSIBLE SOLUTION //
bytes8 conver=0x3FcB875f0000ddC4
bytes8 anothe=0x****0000ddC4

Where 1 ore more of * is != 0

bytes8 another example solution=*0x000100100000ddC4*
bytes8 another example solution=*0x00a10f000000ddC4*

This is what i try:

bytes8 txOriginBytes8= 0x3FcB875f56beddC4;// original 8bytes 0x3FcB875f56beddC4

bytes2 twoBytes= bytes2(uint16(uint64(txOriginBytes8)));// take last two bytes: 0xddC4

bytes4 fourBytes=twoBytes;// add to a four bytes array: 0xddC40000

bytes4 shiftTwoBytes=fourBytes >> 16;// shifting right by two bytes 0x0000ddC4

bytes8 toEithBytes=bytes8(uint64(uint32(shiftTwoBytes)));// put in a bytes8 array 0x000000000000ddc4

return toEithBytes;

Best Answer

I suppose the easiest way is to convert it to bytes, make your modifications and convert it back again like so :

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

contract Example {

  function changeByte8() public view returns (bytes8) {
    bytes8 value = 0x3FcB875f56beddC4;

    // encodePacked the value to get a bytes array
    bytes memory array = abi.encodePacked(value);

    // Set 5th and 6th bytes to 0
    array[4] = 0x00;
    array[5] = 0x00;

    // Ensure that bytes 1 to 4 are != 0
    array[0] = 0xFF;
    array[1] = 0xFF;
    array[2] = 0xFF;
    array[3] = 0xFF; 

    // convert back to bytes8
    return bytes8(array); // 0xffffffff0000ddc4
  }
}

Tell me if you are looking more for an approach based on bit operators and I'll edit my answer.

EDIT : Well actually it's just a few lines, so I add it here too. (I wrote it for clarity, you can be more concise by generating the masks with at the moment they are used) :

 function changeByte8bits() public view returns (bytes8) {
    bytes8 value = 0x3FcB875f56beddC4;

    // Bit mask to select bytes 1 to 4
    bytes8 mask14 = 0xFFFFFFFF00000000;

    // Bit mask to select bytes 5 to 6
    bytes8 mask56 = 0x00000000FFFF0000;

    // Ensure that all bits in bytes 1 to 4 are set
    value = value | mask14;

    // Ensure that all bits in bytes 5 to 6 are unset
    value = value & ~mask56;

    return value; // 0xffffffff0000ddc4
  }
Related Topic