Module Common
    Public Function FormatHex(ByVal HexStr As String) As String
        Dim i As Integer = 0
        Dim numChars As Integer = 0
        Dim outHexStr As String = ""
        Dim cc As Char = ""

        For i = 0 To (Len(HexStr) - 1)
            cc = UCase(HexStr.Chars(i))
            If cc = "0" Or cc = "1" Or cc = "2" Or cc = "3" Or cc = "4" Or cc = "5" Or cc = "6" _
               Or cc = "7" Or cc = "8" Or cc = "9" Or cc = "A" Or cc = "B" Or cc = "C" Or cc = "D" _
               Or cc = "E" Or cc = "F" Then
                outHexStr = outHexStr + cc
                If numChars Mod 2 Then
                    outHexStr = outHexStr + " "
                End If
                numChars = numChars + 1
            End If
        Next i

        ' Trim trailing space
        outHexStr = outHexStr.Trim()

        Return outHexStr
    End Function

    Public Function ReadHex(ByVal HexStr As String) As Byte()
        Dim i As Integer = 0
        Dim numChars As Integer = 0
        Dim ByteCount As Integer = 0
        Dim outHexArray((ReadCountOfHexChars(HexStr) \ 2) - 1) As Byte
        Dim cc As Char = ""
        Dim accumulator As Byte

        If HexStr.Length < 2 Then
            ' MessageBox.Show("Fatal error converting hex string")
            Return outHexArray
        End If

        For i = 0 To HexStr.Length - 1
            cc = HexStr.Chars(i)
            If TranslateHex(cc) <> 255 Then
                numChars += 1
                accumulator += TranslateHex(cc)
                If numChars Mod 2 Then
                    accumulator *= 16
                Else
                    outHexArray(ByteCount) = accumulator
                    ByteCount += 1
                    accumulator = 0
                End If
            End If
        Next i

        Return outHexArray
    End Function

    Public Function ReadCountOfHexChars(ByVal HexStr As String) As Integer
        Dim i As Integer
        Dim length As Integer = 0

        For i = 0 To HexStr.Length - 1
            If TranslateHex(HexStr.Chars(i)) < 16 Then
                length += 1
            End If
        Next i

        Return length
    End Function

    ' returns 255 if error
    Private Function TranslateHex(ByVal HexChar As Char) As Byte
        Select Case UCase(HexChar)
            Case "0" : Return 0
            Case "1" : Return 1
            Case "2" : Return 2
            Case "3" : Return 3
            Case "4" : Return 4
            Case "5" : Return 5
            Case "6" : Return 6
            Case "7" : Return 7
            Case "8" : Return 8
            Case "9" : Return 9
            Case "A" : Return 10
            Case "B" : Return 11
            Case "C" : Return 12
            Case "D" : Return 13
            Case "E" : Return 14
            Case "F" : Return 15
            Case Else : Return 255
        End Select
    End Function

    Public Function CopyArrayPart(ByRef Data As Byte(), ByVal CopyStart As Integer, ByVal Length As Integer) As Byte()
        Dim iteration As Integer
        Dim Result(Length - 1) As Byte

        For iteration = 0 To Length - 1
            Result(iteration) = Data(CopyStart + iteration)
        Next

        Return Result
    End Function

    ' returns 1 if valid, 0 if invalid, -1 if error
    Public Function ArrayEquals(ByRef Array1 As Byte(), ByRef Array2 As Byte(), Optional ByVal LengthToCompare As Integer = 0, Optional ByVal Array1OffS As Integer = 0, Optional ByVal Array2OffS As Integer = 0) As Integer
        If LengthToCompare = 0 Then
            LengthToCompare = Array1.Length
        End If

        If Array1.Length = 0 And Array2.Length = 0 Then
            Return (-1)
        End If

        If Array1.Length <> Array2.Length And Array1OffS = 0 And Array2OffS = 0 Then
            Return 0
        End If

        For iteration = 1 To LengthToCompare
            If Array1(iteration - 1 + Array1OffS) <> Array2(iteration - 1 + Array2OffS) Then
                Return 0
            End If
        Next

        Return 1
    End Function
End Module
