VB.NET - 如何计算字节数组的奇偶校验位

时间:2014-08-09 21:41:24

标签: vb.net byte bytearray

在字节数组中计算奇偶校验位(如果有效位数是奇数还是偶数)的最有效方法是什么?我已经迭代了所有的位并总结了有效位,但这纯粹基于较大字节数组/文件所需的迭代次数而非常不切实际。

3 个答案:

答案 0 :(得分:1)

为了您的方便(以及我的好奇心),我使用奇偶校验查找表进行了一些时序测试,与目前建议的其他两种方法相比:

Module Module1

    Dim rand As New Random

    Dim parityLookup(255) As Integer

    Sub SetUpParityLookup()
        ' setBitsCount data from http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer

        Dim setBitsCount = {
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
    }
        For i = 0 To 255
            parityLookup(i) = setBitsCount(i) And 1
        Next

    End Sub

    ' Method using lookup table
    Function ParityOfArray(a() As Byte) As Integer
        Dim parity As Integer = 0 ' use an Integer because they are faster
        For i = 0 To a.Length - 1
            parity = parity Xor parityLookup(a(i))
        Next

        Return parity

    End Function

    ' Method by Alireza
    Function ComputeParity(bytes() As Byte) As Byte
        Dim parity As Boolean = False
        For i As Integer = 0 To bytes.Length - 1
            Dim b As Byte = bytes(i)
            While b <> 0
                parity = Not parity
                b = CByte(b And (b - 1))
            End While
        Next
        Return Convert.ToByte(parity)
    End Function

    ' Method by dbasnett
    Function CountBits(byteArray As Byte()) As Integer
        Dim rv As Integer = 0
        For Each b As Byte In byteArray
            Dim count As Integer = b
            count = ((count >> 1) And &H55) + (count And &H55)
            count = ((count >> 2) And &H33) + (count And &H33)
            count = ((count >> 4) And &HF) + (count And &HF)
            rv += count
        Next
        Return rv
    End Function

    Sub FillWithRandomBytes(ByRef a() As Byte)
        rand.NextBytes(a)
    End Sub

    Sub Main()
        SetUpParityLookup()

        Dim nBytes = 10000
        Dim a(nBytes - 1) As Byte
        FillWithRandomBytes(a)

        Dim p As Integer

        Dim sw As New Stopwatch

        sw.Start()
        p = ParityOfArray(a)
        sw.Stop()

        Console.WriteLine("ParityOfArray - Parity: {0} Time: {1}", p, sw.ElapsedTicks)

        sw.Restart()
        p = ComputeParity(a)
        sw.Stop()

        Console.WriteLine("ComputeParity - Parity: {0} Time: {1}", p, sw.ElapsedTicks)

        sw.Restart()
        p = CountBits(a)
        sw.Stop()

        ' Note that the value returned from CountBits should be And-ed with 1.
        Console.WriteLine("CountBits     - Parity: {0} Time: {1}", p And 1, sw.ElapsedTicks)

        Console.ReadLine()

    End Sub

End Module

典型的输出:

ParityOfArray - Parity: 0 Time: 386
ComputeParity - Parity: 0 Time: 1014
CountBits     - Parity: 0 Time: 695

答案 1 :(得分:0)

执行此操作的有效方法是在循环中使用x & (x - 1)操作,直到x变为零。这样,您将仅通过设置为1的位数循环。

在VB.NET中用于字节数组:

Function ComputeParity(bytes() As Byte) As Byte
    Dim parity As Boolean = False
    For i As Integer = 0 To bytes.Length - 1
        Dim b As Byte = bytes(i)
        While b <> 0
            parity = Not parity
            b = b And (b - 1)
        End While
    Next
    Return Convert.ToByte(parity)
End Function

答案 2 :(得分:0)

这是一个计数位的函数。

Private Function CountBits(byteArray As Byte()) As Integer
    Dim rv As Integer = 0
    For x As Integer = 0 To byteArray.Length - 1
        Dim b As Byte = byteArray(x)
        Dim count As Integer = b
        count = ((count >> 1) And &H55) + (count And &H55)
        count = ((count >> 2) And &H33) + (count And &H33)
        count = ((count >> 4) And &HF) + (count And &HF)
        rv += count
    Next
    Return rv
End Function

注意:这段代码来自我几年前发现的一些尖锐的黑客攻击。我将它转换为VB。