如何从单个位代表value1和23位代表value2组成uint值?

问题描述

一些我目前反向工程的游戏在3个字节中存储了两个值。 first value的大小为1 bitsecond value的大小为23 bits

[0] [000 0001 0001 0111 1001 0000] 0石头,71568 att

[1] [000 0000 0010 1001 0000 0111] 1块石头,10511 att

我找到了一种阅读它们的方法

    public byte AddedStonesCount
    {
        get
        {
            byte[] att_plus_stones_count_as_bytes = new byte[4];
            Buffer.Blockcopy(this.Data,21,att_plus_stones_count_as_bytes,3);
            uint att_plus_stones_count = BitConverter.ToUInt32(att_plus_stones_count_as_bytes,0);

            return (byte)(att_plus_stones_count >> 23);
        }
        set
        {
        
        }
    }
    public uint Attack
    {
        get
        {
            byte[] att_plus_stones_count_as_bytes = new byte[4];
            Buffer.Blockcopy(this.Data,0);

            return att_plus_stones_count << 9 >> 9;
        }
        set
        {
        
        }
    }

但是我还需要一种更改它们的方法。那就是我总是出问题的地方。 我尝试进行att & 0x800000来使1 0000 0000 0000 0000 0000受到攻击,但是奇怪的是它给了我0,而不是我期望的值。

在这里做一些测试:

        uint test = 0x80290F; //8399119 - here we store 1 stone added and 10511 attack power
        uint test_composition = 10511 & (0x800000); //this does not give me 8399119 :/

        BitArray ba = new BitArray(BitConverter.GetBytes(test));

        string test_original = string.Empty;
        for (int i = 0; i < ba.Length; i++)
            test_original += ba.Get(i) ? 1 : 0;

        uint att = test << 9 >> 9;

        BitArray ba_att = new BitArray(BitConverter.GetBytes(att));
        string test_att = string.Empty;
        for (int i = 0; i < ba_att.Length; i++)
            test_att += ba_att.Get(i) ? 1 : 0;

        uint stones = test >> 23;

帮助...

例如,当宠物的攻击力为10511且被添加的宝石数量1时,则最终值为8399119

解决方法

要根据石头(0或1)设置位#23,并根据攻击设置位#0 ... 22,请使用按位或运算符:

(stones << 23) | attack