Imports System.IO
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Net.Sockets
Imports System.Security.Cryptography
Imports System.Text
Imports System.Threading
Imports System.ComponentModel
Imports System.Reflection
Imports Newtonsoft.Json

Public Class DataProcessing



    ''' <summary>
    ''' 端口号转换为Byte数组
    ''' </summary>
    ''' <param name="port"></param>
    ''' <returns></returns>
    Public Shared Function GetPortToBytes(port As String)
        Dim bport As Integer = CInt(port)
        Dim ports() As Byte = IntToByteLB(bport)

        Return ports
    End Function

    '字符串转byte 数组
    Public Shared Function GetBytesFromStr(str As String) As Byte()
        Return Encoding.ASCII.GetBytes(str)
    End Function
    'bytes转字符串
    Public Shared Function GetStrFromBytes(bytes() As Byte) As String
        Return Encoding.ASCII.GetString(bytes)
    End Function

    '计算数组CRC16校验

    Public Shared Function GetCRC16(data() As Byte) As Integer
        Dim crc As Integer = &HFFFF
        Dim i As Integer
        Dim j As Integer

        For i = 0 To data.Length - 1
            crc = crc Xor data(i)
            For j = 0 To 7
                If (crc And &H1) <> 0 Then
                    crc = (crc >> 1) Xor &HA001
                Else
                    crc = crc >> 1
                End If
            Next
        Next

        Return crc
    End Function

    ''' <summary>
    ''' Int转2个字节Byte
    ''' 低字节在前，高字节在后
    ''' </summary>
    ''' <param name="i"></param>
    ''' <returns></returns>
    Public Shared Function IntToByteLB(ByVal i As Integer) As Byte()
        Dim btemp() As Byte = {0, 0}
        Dim b() As Byte = BitConverter.GetBytes(i)
        btemp(0) = b(1)
        btemp(1) = b(0)
        Return btemp
    End Function
    ''' <summary>
    ''' Int转4个字节Byte
    ''' 低字节在前，高字节在后
    ''' </summary>
    ''' <param name="i"></param>
    ''' <returns></returns>
    Public Shared Function IntToByteLxxB(ByVal i As Integer) As Byte()
        Dim btemp() As Byte = {0, 0, 0, 0}
        Dim b() As Byte = BitConverter.GetBytes(i)
        btemp(0) = b(3)
        btemp(1) = b(2)
        btemp(2) = b(1)
        btemp(3) = b(0)
        Return btemp
    End Function
    Public Shared Function IntToByteHxxB(ByVal i As Integer) As Byte()
        Dim btemp() As Byte = {0, 0, 0, 0}
        Dim b() As Byte = BitConverter.GetBytes(i)
        btemp(0) = b(0)
        btemp(1) = b(1)
        btemp(2) = b(2)
        btemp(3) = b(3)
        Return btemp
    End Function


    ''' <summary>
    ''' Int转2个字节Byte
    ''' 高字节在前,低字节在后
    ''' </summary>
    ''' <param name="i"></param>
    ''' <returns></returns>
    Public Shared Function IntToByteHB(ByVal i As Integer) As Byte()
        Dim btemp() As Byte = {0, 0}
        Dim b() As Byte = BitConverter.GetBytes(i)
        btemp(0) = b(0)
        btemp(1) = b(1)
        Return btemp
    End Function


    ''' <summary>
    ''' 获取文件的MD5值
    ''' 返回Byte数组值
    ''' </summary>
    ''' <param name="filepath">文件路径</param>
    ''' <returns></returns>
    Public Shared Function GetMd5(filepath As String) As Byte()
        Dim FileStr As FileStream = New FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim data(FileStr.Length - 1) As Byte
        FileStr.Read(data, 0, data.Length)

        Dim md5s As Byte() = MD5.Create().ComputeHash(data)
        'Dim fileMd5 As New StringBuilder()
        'Dim i As Integer
        'For i = 0 To md5s.Length - 1
        '    fileMd5.Append(md5s(i).ToString("x2"))
        'Next

        'Console.WriteLine($"MD5:{fileMd5}")

        Return md5s
    End Function


    ''' <summary>
    ''' 获取文件的MD5值
    ''' 返回String字符串
    ''' </summary>
    ''' <param name="filepath">文件路径</param>
    ''' <returns></returns>
    Public Shared Function GetMd5String(filepath As String) As String
        Dim FileStr As FileStream = New FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim data(FileStr.Length) As Byte
        FileStr.Read(data, 0, data.Length)

        Dim md5s As Byte() = MD5.Create().ComputeHash(data)
        Dim fileMd5 As New StringBuilder()
        Dim i As Integer
        For i = 0 To md5s.Length - 1
            fileMd5.Append(md5s(i).ToString("x2"))
        Next

        Console.WriteLine($"MD5:{fileMd5}")

        Return fileMd5.ToString()
    End Function

    ''' <summary>
    ''' 获取本地可用IP
    ''' </summary>
    ''' <returns></returns>
    Public Shared Function GetLocalIp() As List(Of IPAddress)
        Dim address() As IPAddress
        Dim destAddress As New List(Of IPAddress)
        address = Dns.GetHostEntry(Dns.GetHostName()).AddressList
        For Each pAddress As IPAddress In address
            If pAddress.AddressFamily = AddressFamily.InterNetwork Then
                destAddress.Add(pAddress)
            End If
        Next
        Return destAddress
    End Function
    ''' <summary>
    ''' Byte数组转字符串
    ''' </summary>
    ''' <param name="databuff"></param>
    ''' <returns></returns>
    Public Shared Function ByteToString(databuff() As Byte)
        Dim strData As String = String.Empty
        For i = 0 To databuff.Length - 1
            strData &= $" {Hex(databuff(i)).PadLeft(2, "0"c)}"
        Next
        Return strData
    End Function
    Public Shared Function ByteToString2(databuff() As Byte)
        Dim strData As String = String.Empty
        For i = 0 To databuff.Length - 1
            strData &= $" {ByteToHex1(databuff(i)).PadLeft(2, "0"c)}"
        Next
        Return strData
    End Function

    '将16进制字符串转换为字节数组
    Public Shared Function HexStringToByteArray(hex As String) As Byte()

        Dim bytes As New List(Of Byte)
        hex = hex.Replace(" ", "").Trim.ToUpper()
        For i As Integer = 0 To hex.Length - 1 Step 2
            Dim hexByte As String = hex.Substring(i, 2)
            bytes.Add(Convert.ToByte(hexByte, 16))
        Next
        Return bytes.ToArray()
    End Function

    '将字节数组转换为16进制字符串
    Public Shared Function ByteArrayToHexString(bytes As Byte()) As String
        If bytes Is Nothing OrElse bytes.Length = 0 Then Return ""
        Dim hex As String = ""
        For Each b As Byte In bytes
            hex += b.ToString("X2") & " "
        Next
        Return hex.Trim()

    End Function
    'byte 转16进制字符串
    Public Shared Function ByteToHex1(ByVal b As Byte) As String
        Return b.ToString("X2")
    End Function
    '16进制字符串 转byte数组
    'Public Shared Function HexToByte(ByVal hex As String) As Byte()
    '    Dim result As Byte() = New Byte(hex.Length / 2 - 1) {}
    '    For i As Integer = 0 To hex.Length - 1 Step 2
    '        result(i / 2) = Convert.ToByte(hex.Substring(i, 2), 16)

    '    Next
    'End Function



    ''' <summary>
    ''' 等待回复
    ''' </summary>
    ''' <param name="isReply">是否回复标志位</param>
    ''' <param name="TimeOut">超时时间</param>
    Public Shared Sub WaitReply(isReply As Boolean, TimeOut As Integer)   'ByRef
        Dim tick As Integer
        Dim startTick As Integer = My.Computer.Clock.TickCount
        isReply = False
        While isReply = False AndAlso tick <= TimeOut
            Thread.Sleep(3)
            tick = My.Computer.Clock.TickCount - startTick
            Application.DoEvents()
        End While
    End Sub



    ''' <summary>
    ''' 延时N秒
    ''' </summary>
    ''' <param name="HowLong">延时时间值</param>
    Public Shared Sub PauseWait(ByVal HowLong As Long)
        Dim tick As Long
        tick = My.Computer.Clock.TickCount
        Do
            My.Application.DoEvents()
        Loop Until tick + HowLong < My.Computer.Clock.TickCount
    End Sub

    ''' <summary>
    ''' IP地址转换为Byte数组
    ''' </summary>
    ''' <param name="addr"></param>
    ''' <returns></returns>
    Public Shared Function GetAddressToBytes(addr As String)
        Dim iadd() As String = addr.Split(New Char() {"."c}, StringSplitOptions.RemoveEmptyEntries)
        Dim address(3) As Byte
        address(0) = iadd(0)    '例：192
        address(1) = iadd(1)    '例：168
        address(2) = iadd(2)
        address(3) = iadd(3)

        Return address
    End Function

    ''' <summary>
    ''' 获取字符串的MD5值
    ''' </summary>
    ''' <param name="str">需要求MD5的原文字符串</param>
    ''' <returns></returns>
    Public Shared Function GetStringMd5(str As String) As String
        Dim md5Hasher As New MD5CryptoServiceProvider()
        Dim data As Byte() = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(str))
        Dim fileMd5 As New StringBuilder()
        Dim i As Integer
        For i = 0 To data.Length - 1
            fileMd5.Append(data(i).ToString("X2"))
        Next

        Return fileMd5.ToString()
    End Function


    ''' <summary>
    ''' 分块函数
    ''' 计算Byte数组的块数
    ''' </summary>
    ''' <param name="databuff"></param>
    ''' <param name="size"></param>
    ''' <returns></returns>
    Public Shared Function GetBlocks(databuff As Byte(), size As Integer) As Integer
        Dim blockCount As Integer = databuff.Length \ size
        If databuff.Length Mod size > 0 Then
            blockCount += 1
        End If
        Return blockCount
    End Function


    ''' <summary>
    ''' 字符串转换Byte数组
    ''' 字符串为连续且不包含任意字符的字符串
    ''' </summary>
    ''' <param name="str"></param>
    ''' <returns></returns>
    Public Shared Function GetStringToDataByte(str As String) As Byte()
        Dim dataList As New List(Of Byte)

        For index As Integer = 0 To str.Length - 1 Step 2
            dataList.Add($"&H{str.Substring(index, 2)}")
        Next

        Return dataList.ToArray
    End Function

    ''' <summary>
    ''' 把UNIX时间戳转换为标准时间
    ''' </summary>
    ''' <param name="intTime">要转换的UNIX时间戳</param>
    ''' <param name="ime">时区</param>
    ''' <returns>intTime所代表的标准时间</returns>
    Public Shared Function FromUnixTime(intTime As Long, ime As Long) As Date
        'If intTime Is Nothing Or Not IsNumeric(intTime) Then 
        '    FromUnixTime = Now()
        '    Exit Function
        'End If
        'If intTime Is Nothing Or Not IsNumeric(intTimeZone) Then intTimeZone = 0
        'FromUnixTime = DateAdd("s", intTime, "1970-1-1 0:0:0")
        'FromUnixTime = DateAdd("h", intTimeZone, FromUnixTime)

        Dim a As Date = DateTime.Parse("1970-1-1 0:0:0")
        a = a.AddSeconds(intTime)
        a = a.AddHours(ime)

        Return a
    End Function


    ''' <summary>
    ''' 和校验取余数
    ''' 求Byte数组的和校验取余数
    ''' </summary>
    ''' <param name="dataPacket">Byte数组</param>
    ''' <returns></returns>
    Public Shared Function SumAndMod(dataPacket As Byte()) As Byte
        Dim sum As Integer
        For idx = 0 To dataPacket.Length - 1
            sum += dataPacket(idx)
            sum = sum And &HFF
        Next
        Dim sumMod As Byte = &HFF - sum
        Return sumMod
    End Function
    Public Shared Sub Delay(ByVal time As Integer)
        Dim timeEnd As Integer = My.Computer.Clock.TickCount + time
        Do
            Application.DoEvents()
        Loop Until My.Computer.Clock.TickCount > timeEnd
    End Sub

    ''' <summary>
    ''' 获取枚举描述特性
    ''' </summary>
    ''' <param name="enumValue">需要获取特性的枚举值</param>
    ''' <returns>枚举描述特性</returns>
    Public Shared Function GetEnumDescription(enumValue As [Enum]) As String

        Dim fi As FieldInfo = enumValue.GetType().GetField(enumValue.ToString())
        Dim attr() As DescriptionAttribute =
                DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute),
                                                  False), DescriptionAttribute())

        If attr.Length > 0 Then
            Return attr(0).Description
        Else
            Return enumValue.ToString()
        End If
    End Function

End Class
