簡體   English   中英

在 C# 中屏蔽字節數組

[英]Masking a byte array in C#

我需要在 C# 中屏蔽一個字節數組,以便我可以比較它。 我有一個已知的字節數組 (TDO),其中一些位是關心的,而其中一些是不關心的。 哪些位是關心和不關心的由掩碼字節數組描述。 1 是關心​​,0 是不關心。

現在,我必須將 TDO 與掩碼數組相關聯,以便我可以將 TDO 與另一個字節數組進行比較。 有人可以幫我開始嗎?

我搜索了一個類似的例子,但沒有找到任何東西。

編輯:我想做這樣的事情 - 但我不知道如何開始..

byte[] tdo = new byte[] {28, 82} //1C 52 in hex
byte[] mask = new byte[] {255, 3} //FF 03 in hex 

bit[] tdo_bit = ByteToBit(tdo) = {0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0}
bit[] mask_bit = ByteToBit(mask) = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1}

bit[] legal_tdo = bit[] {0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0}

MaskCompare(tdo_bit, mask_bit, legal_tdo)
{
  //compares tdo_bit with legal_tdo, but the bits where mask_bit is 0 doesn't 
  //make tdo_bit != legal_tdo
}

您實際上不需要將其轉換為位數組。 您可以使用按位和運算符屏蔽兩個字節數組,如下所示:

bool AreEqual(byte[] a, byte[] b, byte[] mask)
{
    for(int i = 0; i < a.Length; i ++)
    {
        if ((a[i] & mask[i]) != (b[i] & mask[i])) return false;
    }
    return true;
}

我想了很久,很辛苦。

解決方案涉及基本的布爾理論。 我會用| 作為“OR”, &作為“AND”,與 C# 使用的語法相同。

OR :如果任何輸入為 1,則返回 1,否則返回 0。
AND :如果所有輸入都是 1,則返回 1,否則返回 0。

僅使用 OR 和 AND,對二進制數有 4 種可能的操作。

  1. x | 1 => 1 x | 1 => 1 (總是返回 1)
    例如。 0 | 1 => 1 0 | 1 => 1 , 1 | 1 => 1 1 | 1 => 1

  2. x | 0 => x x | 0 => x (身份,因為它返回自身)
    例如。 0 | 0 => 0 0 | 0 => 0 , 1 | 0 => 1 1 | 0 => 1

  3. x & 1 => 1 (身份,因為它返回自身)
    例如。 0 & 1 => 0 , 1 & 1 => 1

  4. x & 0 => y' (返回與輸入相反的值)
    例如。 0 & 0 => 1 , 1 & 0 => 0

注意:適用於單個位的方法適用於整個字節,因此我將使用位作為示例。

讓我們假設 a = 0, b = 1。為此我們可以使用規則 1 和 2。

ma = a | m.
mb = b | m.
same = ma & mb.

我們來分析一下代碼。 如果 m 為 1,則結果始終為 1。如果 m 為 0,則檢查 a 和 b 是否相同。

OP注意事項:
使用此解決方案,掩碼需要為 1 表示 NOT CARE,0 表示 CARE。 但是,OP 想用 1 表示關心,用 0 表示不關心。 解決方法很簡單。 我們需要做的就是“否定”或“反轉”掩碼。 我們可以使用規則 4. inversed_m = m & 0並在其余代碼中使用 inverse_m 而不是 m 。

如果您可以對一個字節執行此操作,則可以使用 for 循環對整個字節列表/數組執行相同操作。 這是工作代碼。

bool AreEqual(byte[] a, byte[] b, byte[] mask)
{
    for(int i = 0; i < a.Length; i ++)
    {
        var byteA = a[i];
        var byteB = b[i];
        var byteMask = mask[i];

        // If mask value 0 is "check" and 1 is "don't check", do nothing. 
        // Otherwise (if you are like OP), uncomment next line
        // byteMask = byteMask & 0;  // "negate" / "inverse" byteMask

        var maskedByteA = byteA | byteMask;
        var maskedByteB = byteB | byteMask;

        var same = maskedByteA & maskedByteB;

        if (!same)
        {
            return false;
        }
    }
    return true;
}

警告:接受的答案似乎是錯誤的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM