Back and forth calculation of integer Identifier using bit shifting and OR operations

Good morning, don't know if this question is hitting the right StackExchange network. If not please forgive me.

I got an decimal/integer identifier value which i need to split into three separate values. Lets assume we have program ABC. Program ABC is generating the decimal/integer identifier value using this formula:

int identifier = 0;
int unitTypeId = 1;
int boardId = 4;
int messageId = 20;

identifier = (((unitTypeId) << 8) | ((boardId) << 5) | (messageId));

identifier does now contain a value based on the bit shift and OR operation.

Now we have to develop Program CDE. Program CDE reads out an log file which contains the decimal/integer identifier and some other values which are not necessary for this case. Program CDE has to split the read identifier into the the three values:

int unitTypeId = 1;
int boardId = 4;
int messageId = 20;

First: Is there a way to achieve this?

My first attempt looks like this, but to be honest i don't get the origin values which the identifier is based on.

private void resolveIdentifier()
{
    this.IdentifierBits = Convert.ToString(this.OriginIdentifier, 2); //Convert to binary in a string

    // Message identifiers are constructed:         
    // Unit Type                    Bit 8-10
    // Board ID                     Bit 5-7
    // Unit Specific Message Ids    Bit 0-4

    int[] bits = this.IdentifierBits.PadLeft(11, '0') // Add 0's from left
                     .Select(c => int.Parse(c.ToString())) // convert each char to int
                     .ToArray(); // Convert IEnumerable from select to Array

    Array.Reverse(bits);

    for (int i = 0; i < bits.Length; i++)
    {
        int calcValue = i;
        if (i < 5) // Message Id
        {
            this.MessageId += (int)Math.Pow(2, calcValue);
        }
        else if (i > 4 && i < 8)
        {
            calcValue -= 5;
            this.BoardId += (int)Math.Pow(2, calcValue);
        }
        else
        {
            calcValue -= 8;
            this.Unit += (int)Math.Pow(2, calcValue);
        }
    }
}

Can somebody tell me what I'm doing wrong and if its even possible to get to the origin three values?

Jon Skeet
people
quotationmark

Just mask and shift. You've already got a comment describing the format:

// Message identifiers are constructed:         
// Unit Type                    Bit 8-10
// Board ID                     Bit 5-7
// Unit Specific Message Ids    Bit 0-4

So the reversal code is:

int messageId = identifier & 0x1f;
int boardId = (identifier >> 5) & 7;
int unitType = (identifier >> 8) & 7;

Here 0x1f is 11111 in binary - so "anding" with that just leaves the bottom 5 bits. 7 is 111 in binary - so "anding" with that just leaves the bottom 3 bits, which is what you want from identifier for boardId and unitType after you've shift the values a bit.

If you're still slightly confused about how that works, I suggest you try some values on paper, showing everything in binary - start with a message ID, board ID and unit type, construct your identifier (possibly drawing lines between the different parts of the number) and then see what happens when you apply the shifting/masking as above.

people

See more on this question at Stackoverflow