home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 7_2009-2012.ISO / data / zips / Hex_string219759262011.psc / HexStringFormat.bas < prev    next >
BASIC Source File  |  2011-02-06  |  28KB  |  699 lines

  1. Attribute VB_Name = "HexStringFormat"
  2. ' all these functions work with formatted hex strings
  3. ' this means strings that contain spaces or line changes are accepted
  4. Option Explicit
  5.  
  6. Private Const CRYPT_HEX_FORMAT = "00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00"
  7.  
  8. Private Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (Arr() As Any) As Long
  9. Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Ptr As Long, ByVal Value As Long)
  10. Private Declare Function SysAllocStringByteLen Lib "oleaut32" (ByVal Ptr As Long, ByVal Length As Long) As Long
  11. Private Declare Function SysAllocStringLen Lib "oleaut32" (ByVal Ptr As Long, ByVal Length As Long) As Long
  12.  
  13. Private LH(0 To 5) As Long, LHP As Long
  14. Private LA() As Long, LP As Long
  15.  
  16. Private IH(0 To 5) As Long, IHP As Long
  17. Private IA() As Integer, IP As Long
  18.  
  19. Private LH_(0 To 5) As Long, LHP_ As Long
  20. Private LA_() As Long, LP_ As Long
  21.  
  22. Private BHex(0 To 511) As Long, BHexI As Boolean
  23.  
  24. ' a very advanced function: allows for many kinds of formatting options and it is very fast too
  25. Public Function BytesToHexString_F1(Bytes() As Byte, Optional Format As String = CRYPT_HEX_FORMAT, Optional Separator As String = vbNewLine, Optional ByVal Lowercase As Boolean = True) As String
  26.     Dim BytesBase As Long, BytesPtr As Long, StringPtr As Long
  27.     Dim C As Long, CH As Long, CL As Long, CS As Long, F() As Long, I As Long, J As Long, L As Long, LF As Long, LS As Long, P As Long
  28.     ' get pointer to safe array header
  29.     BytesPtr = Not Not Bytes: Debug.Assert App.hInstance
  30.     ' valid array
  31.     If BytesPtr <> 0 Then
  32.         ' calculate size
  33.         L = UBound(Bytes) - LBound(Bytes) + 1
  34.         ' valid size
  35.         If L > 0 Then
  36.             ' safe arrays prepared for use?
  37.             If IHP = 0 Then
  38.                 ' safe array: Long
  39.                 LH(0) = 1: LH(1) = 4: LH(4) = &H3FFFFFFF
  40.                 LHP = VarPtr(LH(0))
  41.                 LP = ArrPtr(LA)
  42.                 ' safe array: Integer
  43.                 IH(0) = 1: IH(1) = 2
  44.                 IHP = VarPtr(IH(0))
  45.                 IP = ArrPtr(IA)
  46.             End If
  47.             ' hex array prepared for use?
  48.             If BHexI = False Then
  49.                 For I = 0 To 255
  50.                     ' upper case
  51.                     CH = ((I And &HF0&) \ &H10&) Or &H30&
  52.                     If CH > 57& Then CH = CH + 7&
  53.                     CL = (I And &HF&) Or &H30&
  54.                     If CL > 57& Then CL = CL + 7&
  55.                     BHex(I) = CH Or (CL * &H10000)
  56.                     ' lower case
  57.                     If CH > 64& Then CH = CH Or &H20&
  58.                     If CL > 64& Then CL = CL Or &H20&
  59.                     BHex(I Or 256&) = CH Or (CL * &H10000)
  60.                 Next I
  61.                 BHexI = True
  62.             End If
  63.             
  64.             ' safe array: Long (first to get better speed)
  65.             PutMem4 LP, LHP
  66.             
  67.             ' fast mode or format mode?
  68.             If InStr(Format, "00") = 0 Then
  69.                 ' prepare buffer
  70.                 StringPtr = SysAllocStringByteLen(0, L * 4&)
  71.                 LH(3) = VarPtr(BytesToHexString_F1): LA(0) = StringPtr
  72.                 ' modify byte array to zero base
  73.                 If LBound(Bytes) <> 0 Then
  74.                     LH(3) = BytesPtr
  75.                     BytesBase = LA(5)
  76.                     LA(5) = 0
  77.                 End If
  78.                 ' point long array to string buffer
  79.                 LH(3) = StringPtr
  80.                 ' convert the bytes
  81.                 If Lowercase = False Then
  82.                     For I = 0 To UBound(Bytes): LA(I) = BHex(Bytes(I)): Next
  83.                 Else
  84.                     For I = 0 To UBound(Bytes): LA(I) = BHex(Bytes(I) Or 256&): Next
  85.                 End If
  86.                 ' restore byte array to non-zero base
  87.                 If BytesBase <> 0 Then LH(3) = BytesPtr: LA(5) = BytesBase
  88.             Else
  89.                 LF = Len(Format)
  90.                 LS = Len(Separator)
  91.                 ' find out how many bytes we output per line
  92.                 ReDim F(0 To LF \ 2 - 1)
  93.                 I = 0
  94.                 Do
  95.                     Do: I = InStrB(I + 1, Format, "00")
  96.                     Loop Until (I = 0&) Or (I And 1&) = 1&
  97.                     If I <> 0& Then
  98.                         F(C) = (I - 1&)
  99.                         C = C + 1&
  100.                         I = I + 3
  101.                     End If
  102.                 Loop Until I = 0&
  103.                 ReDim Preserve F(C - 1)
  104.                 ' calculate separator & amount of characters after last line
  105.                 CL = L - 1
  106.                 If LS <> 0& Then CS = LS * (CL \ C)
  107.                 If (L Mod C) <> 0& Then CS = CS + F(CL Mod C) \ 2& + 2&
  108.                 ' prepare buffer
  109.                 StringPtr = SysAllocStringLen(0, LF * (L \ C) + CS)
  110.                 LH(3) = VarPtr(BytesToHexString_F1): LA(0) = StringPtr
  111.                 ' replicate
  112.                 Mid$(BytesToHexString_F1, 1, LF) = Format
  113.                 If Len(BytesToHexString_F1) > LF Then
  114.                     Mid$(BytesToHexString_F1, 1 + LF, LS) = Separator
  115.                     Mid$(BytesToHexString_F1, 1 + LF + LS) = BytesToHexString_F1
  116.                 End If
  117.                 ' modify byte array to zero base
  118.                 If LBound(Bytes) <> 0 Then
  119.                     LH(3) = BytesPtr
  120.                     BytesBase = LA(5)
  121.                     LA(5) = 0
  122.                 End If
  123.                 P = StringPtr
  124.                 LS = (LF + LS) * 2&
  125.                 ' convert the bytes
  126.                 If Lowercase = False Then
  127.                     For I = 0 To UBound(Bytes) - C + 1 Step C
  128.                         For J = 0 To C - 1
  129.                             LH(3) = P + F(J)
  130.                             LA(0) = BHex(Bytes(I + J))
  131.                         Next J
  132.                         P = P + LS
  133.                     Next I
  134.                     If (L Mod C) <> 0& Then
  135.                         For J = 0 To CL Mod C
  136.                             LH(3) = P + F(J)
  137.                             LA(0) = BHex(Bytes(I + J))
  138.                         Next J
  139.                     End If
  140.                 Else
  141.                     For I = 0 To UBound(Bytes) - C + 1 Step C
  142.                         For J = 0 To C - 1
  143.                             LH(3) = P + F(J)
  144.                             LA(0) = BHex(Bytes(I + J) Or 256&)
  145.                         Next J
  146.                         P = P + LS
  147.                     Next I
  148.                     If (L Mod C) <> 0& Then
  149.                         For J = 0 To CL Mod C
  150.                             LH(3) = P + F(J)
  151.                             LA(0) = BHex(Bytes(I + J) Or 256&)
  152.                         Next J
  153.                     End If
  154.                 End If
  155.                 ' restore byte array to non-zero base
  156.                 If BytesBase <> 0 Then LH(3) = BytesPtr: LA(5) = BytesBase
  157.             End If
  158.             
  159.             ' safe array: Long
  160.             LH(3) = LP: LA(0) = 0
  161.         End If
  162.     End If
  163. End Function
  164.  
  165. ' a very fast function that also allows for any kind of hex string input
  166. ' supports upper & lowercase and any non-hex character pair or lone character is simply ignored
  167. Public Function HexStringToBytes_F1(Hex As String) As Byte()
  168.  
  169.     Dim B() As Byte, C As Long, CH As Long, CL As Long, H As Long, I As Long, J As Long, L As Long, LB As Long
  170.     
  171.     L = Len(Hex)
  172.     If L > 1 Then
  173.         ' safe arrays prepared for use?
  174.         If IHP = 0 Then
  175.             ' safe array: Long
  176.             LH(0) = 1: LH(1) = 4: LH(4) = &H3FFFFFFF
  177.             LHP = VarPtr(LH(0))
  178.             LP = ArrPtr(LA)
  179.             ' safe array: Integer
  180.             IH(0) = 1: IH(1) = 2
  181.             IHP = VarPtr(IH(0))
  182.             IP = ArrPtr(IA)
  183.         End If
  184.         
  185.         ' safe array: Long (first to get better speed)
  186.         PutMem4 LP, LHP
  187.         ' safe array: Integer
  188.         LH(3) = IP: LA(0) = IHP
  189.         
  190.         ' prepare output byte array
  191.         HexStringToBytes_F1 = vbNullString
  192.         ' get pointer to safe array header for manipulation
  193.         LH(3) = Not Not HexStringToBytes_F1: Debug.Assert App.hInstance
  194.         ' calculate size of BSTR allocation
  195.         LB = (L \ 2) - 6: If LB < 0 Then LB = 0
  196.         ' create a BSTR, it works as our byte array!
  197.         LA(3) = SysAllocStringByteLen(0, LB) - 4: LA(4) = LB + 6
  198.         
  199.         ' access string via Integer array
  200.         IH(3) = StrPtr(Hex): IH(4) = L
  201.         ' set long array to output data (= byte array)
  202.         LH(3) = LA(3)
  203.         
  204.         Do
  205.             ' byte 1
  206.             Do While I + 1 < L
  207.                 CH = IA(I)
  208.                 Select Case CH
  209.                 Case 48 To 57
  210.                     I = I + 1
  211.                     CL = IA(I)
  212.                     Select Case CL
  213.                     Case 48 To 57
  214.                         H = ((CH And Not 48&) * &H10&) Or (CL And Not 48&)
  215.                         C = 1
  216.                         Exit Do
  217.                     Case 65 To 70
  218.                         H = ((CH And Not 48&) * &H10&) Or (CL - 55&)
  219.                         C = 1
  220.                         Exit Do
  221.                     Case 97 To 102
  222.                         H = ((CH And Not 48&) * &H10&) Or (CL - 87&)
  223.                         C = 1
  224.                         Exit Do
  225.                     End Select
  226.                 Case 65 To 70
  227.                     I = I + 1
  228.                     CL = IA(I)
  229.                     Select Case CL
  230.                     Case 48 To 57
  231.                         H = ((CH - 55&) * &H10&) Or (CL And Not 48&)
  232.                         C = 1
  233.                         Exit Do
  234.                     Case 65 To 70
  235.                         H = ((CH - 55&) * &H10&) Or (CL - 55&)
  236.                         C = 1
  237.                         Exit Do
  238.                     Case 97 To 102
  239.                         H = ((CH - 55&) * &H10&) Or (CL - 87&)
  240.                         C = 1
  241.                         Exit Do
  242.                     End Select
  243.                 Case 97 To 102
  244.                     I = I + 1
  245.                     CL = IA(I)
  246.                     Select Case CL
  247.                     Case 48 To 57
  248.                         H = ((CH - 87&) * &H10&) Or (CL And Not 48&)
  249.                         C = 1
  250.                         Exit Do
  251.                     Case 65 To 70
  252.                         H = ((CH - 87&) * &H10&) Or (CL - 55&)
  253.                         C = 1
  254.                         Exit Do
  255.                     Case 97 To 102
  256.                         H = ((CH - 87&) * &H10&) Or (CL - 87&)
  257.                         C = 1
  258.                         Exit Do
  259.                     End Select
  260.                 End Select
  261.                 I = I + 1
  262.             Loop
  263.             ' done?
  264.             If I + 2 < L Then I = I + 1 Else Exit Do
  265.             ' byte 2
  266.             Do While I + 1 < L
  267.                 CH = IA(I)
  268.                 Select Case CH
  269.                 Case 48 To 57
  270.                     I = I + 1
  271.                     CL = IA(I)
  272.                     Select Case CL
  273.                     Case 48 To 57
  274.                         H = H Or ((CH And Not 48&) * &H1000&) Or ((CL And Not 48&) * &H100&)
  275.                         C = 2
  276.                         Exit Do
  277.                     Case 65 To 70
  278.                         H = H Or ((CH And Not 48&) * &H1000&) Or ((CL - 55&) * &H100&)
  279.                         C = 2
  280.                         Exit Do
  281.                     Case 97 To 102
  282.                         H = H Or ((CH And Not 48&) * &H1000&) Or ((CL - 87&) * &H100&)
  283.                         C = 2
  284.                         Exit Do
  285.                     End Select
  286.                 Case 65 To 70
  287.                     I = I + 1
  288.                     CL = IA(I)
  289.                     Select Case CL
  290.                     Case 48 To 57
  291.                         H = H Or ((CH - 55&) * &H1000&) Or ((CL And Not 48&) * &H100&)
  292.                         C = 2
  293.                         Exit Do
  294.                     Case 65 To 70
  295.                         H = H Or ((CH - 55&) * &H1000&) Or ((CL - 55&) * &H100&)
  296.                         C = 2
  297.                         Exit Do
  298.                     Case 97 To 102
  299.                         H = H Or ((CH - 55&) * &H1000&) Or ((CL - 87&) * &H100&)
  300.                         C = 2
  301.                         Exit Do
  302.                     End Select
  303.                 Case 97 To 102
  304.                     I = I + 1
  305.                     CL = IA(I)
  306.                     Select Case CL
  307.                     Case 48 To 57
  308.                         H = H Or ((CH - 87&) * &H1000&) Or ((CL And Not 48&) * &H100&)
  309.                         C = 2
  310.                         Exit Do
  311.                     Case 65 To 70
  312.                         H = H Or ((CH - 87&) * &H1000&) Or ((CL - 55&) * &H100&)
  313.                         C = 2
  314.                         Exit Do
  315.                     Case 97 To 102
  316.                         H = H Or ((CH - 87&) * &H1000&) Or ((CL - 87&) * &H100&)
  317.                         C = 2
  318.                         Exit Do
  319.                     End Select
  320.                 End Select
  321.                 I = I + 1
  322.             Loop
  323.             ' done?
  324.             If I + 2 < L Then I = I + 1 Else Exit Do
  325.             ' byte 3
  326.             Do While I + 1 < L
  327.                 CH = IA(I)
  328.                 Select Case CH
  329.                 Case 48 To 57
  330.                     I = I + 1
  331.                     CL = IA(I)
  332.                     Select Case CL
  333.                     Case 48 To 57
  334.                         H = H Or ((CH And Not 48&) * &H100000) Or ((CL And Not 48&) * &H10000)
  335.                         C = 3
  336.                         Exit Do
  337.                     Case 65 To 70
  338.                         H = H Or ((CH And Not 48&) * &H100000) Or ((CL - 55&) * &H10000)
  339.                         C = 3
  340.                         Exit Do
  341.                     Case 97 To 102
  342.                         H = H Or ((CH And Not 48&) * &H100000) Or ((CL - 87&) * &H10000)
  343.                         C = 3
  344.                         Exit Do
  345.                     End Select
  346.                 Case 65 To 70
  347.                     I = I + 1
  348.                     CL = IA(I)
  349.                     Select Case CL
  350.                     Case 48 To 57
  351.                         H = H Or ((CH - 55&) * &H100000) Or ((CL And Not 48&) * &H10000)
  352.                         C = 3
  353.                         Exit Do
  354.                     Case 65 To 70
  355.                         H = H Or ((CH - 55&) * &H100000) Or ((CL - 55&) * &H10000)
  356.                         C = 3
  357.                         Exit Do
  358.                     Case 97 To 102
  359.                         H = H Or ((CH - 55&) * &H100000) Or ((CL - 87&) * &H10000)
  360.                         C = 3
  361.                         Exit Do
  362.                     End Select
  363.                 Case 97 To 102
  364.                     I = I + 1
  365.                     CL = IA(I)
  366.                     Select Case CL
  367.                     Case 48 To 57
  368.                         H = H Or ((CH - 87&) * &H100000) Or ((CL And Not 48&) * &H10000)
  369.                         C = 3
  370.                         Exit Do
  371.                     Case 65 To 70
  372.                         H = H Or ((CH - 87&) * &H100000) Or ((CL - 55&) * &H10000)
  373.                         C = 3
  374.                         Exit Do
  375.                     Case 97 To 102
  376.                         H = H Or ((CH - 87&) * &H100000) Or ((CL - 87&) * &H10000)
  377.                         C = 3
  378.                         Exit Do
  379.                     End Select
  380.                 End Select
  381.                 I = I + 1
  382.             Loop
  383.             ' done?
  384.             If I + 2 < L Then I = I + 1 Else Exit Do
  385.             ' byte 4
  386.             Do While I + 1 < L
  387.                 CH = IA(I)
  388.                 Select Case CH
  389.                 Case 48 To 55
  390.                     I = I + 1
  391.                     CL = IA(I)
  392.                     Select Case CL
  393.                     Case 48 To 57
  394.                         H = H Or ((CH And Not 48&) * &H10000000) Or ((CL And Not 48&) * &H1000000)
  395.                         C = 0
  396.                         Exit Do
  397.                     Case 65 To 70
  398.                         H = H Or ((CH And Not 48&) * &H10000000) Or ((CL - 55&) * &H1000000)
  399.                         C = 0
  400.                         Exit Do
  401.                     Case 97 To 102
  402.                         H = H Or ((CH And Not 48&) * &H10000000) Or ((CL - 87&) * &H1000000)
  403.                         C = 0
  404.                         Exit Do
  405.                     End Select
  406.                 Case 56 To 57
  407.                     I = I + 1
  408.                     CL = IA(I)
  409.                     Select Case CL
  410.                     Case 48 To 57
  411.                         H = H Or ((CH And Not 56&) * &H10000000) Or ((CL And Not 48&) * &H1000000) Or &H80000000
  412.                         C = 0
  413.                         Exit Do
  414.                     Case 65 To 70
  415.                         H = H Or ((CH And Not 56&) * &H10000000) Or ((CL - 55&) * &H1000000) Or &H80000000
  416.                         C = 0
  417.                         Exit Do
  418.                     Case 97 To 102
  419.                         H = H Or ((CH And Not 56&) * &H10000000) Or ((CL - 87&) * &H1000000) Or &H80000000
  420.                         C = 0
  421.                         Exit Do
  422.                     End Select
  423.                 Case 65 To 70
  424.                     I = I + 1
  425.                     CL = IA(I)
  426.                     Select Case CL
  427.                     Case 48 To 57
  428.                         H = H Or ((CH - 63&) * &H10000000) Or ((CL And Not 48&) * &H1000000) Or &H80000000
  429.                         C = 0
  430.                         Exit Do
  431.                     Case 65 To 70
  432.                         H = H Or ((CH - 63&) * &H10000000) Or ((CL - 55&) * &H1000000) Or &H80000000
  433.                         C = 0
  434.                         Exit Do
  435.                     Case 97 To 102
  436.                         H = H Or ((CH - 63&) * &H10000000) Or ((CL - 87&) * &H1000000) Or &H80000000
  437.                         C = 0
  438.                         Exit Do
  439.                     End Select
  440.                 Case 97 To 102
  441.                     I = I + 1
  442.                     CL = IA(I)
  443.                     Select Case CL
  444.                     Case 48 To 57
  445.                         H = H Or ((CH - 95&) * &H10000000) Or ((CL And Not 48&) * &H1000000) Or &H80000000
  446.                         C = 0
  447.                         Exit Do
  448.                     Case 65 To 70
  449.                         H = H Or ((CH - 95&) * &H10000000) Or ((CL - 55&) * &H1000000) Or &H80000000
  450.                         C = 0
  451.                         Exit Do
  452.                     Case 97 To 102
  453.                         H = H Or ((CH - 95&) * &H10000000) Or ((CL - 87&) * &H1000000) Or &H80000000
  454.                         C = 0
  455.                         Exit Do
  456.                     End Select
  457.                 End Select
  458.                 I = I + 1
  459.             Loop
  460.             ' write
  461.             If C = 0 Then LA(J) = H: J = J + 1
  462.             ' done?
  463.             If I + 2 < L Then I = I + 1 Else Exit Do
  464.         Loop
  465.         
  466.         ' check for unwritten bytes & avoid buffer overwrite
  467.         Select Case C
  468.             Case 0
  469.             Case 1: LA(J) = (LA(J) And &HFFFFFF00) Or H
  470.             Case 2: LA(J) = (LA(J) And &HFFFF0000) Or H
  471.             Case 3: LA(J) = (LA(J) And &HFF000000) Or H
  472.         End Select
  473.         
  474.         ' calculate final length
  475.         L = J * 4 + C
  476.         Select Case L
  477.             Case LB + 6 ' do nothing!
  478.             Case 0: HexStringToBytes_F1 = vbNullString
  479.             Case Else
  480.                 LH(3) = ArrPtr(B)
  481.                 LA(0) = Not Not HexStringToBytes_F1: Debug.Assert App.hInstance
  482.                 ReDim Preserve B(0 To L - 1)
  483.                 LA(0) = 0
  484.         End Select
  485.                 
  486.         ' safe array: Integer
  487.         LH(3) = IP: LA(0) = 0
  488.         ' safe array: Long
  489.         LH(3) = LP: LA(0) = 0
  490.     Else
  491.         ' empty array
  492.         HexStringToBytes_F1 = vbNullString
  493.     End If
  494. End Function
  495.  
  496. Public Function z_broken_HexStringToBytes_F2(Hex As String) As Byte()
  497.  
  498.     Dim B() As Byte, C As Long, CH As Long, CL As Long, H As Long, I As Long, J As Long, L As Long, LB As Long
  499.     
  500.     L = Len(Hex)
  501.     If L > 1 Then
  502.         ' safe arrays prepared for use?
  503.         If LHP_ = 0 Then
  504.             ' safe array: Long
  505.             LH(0) = 1: LH(1) = 4: LH(4) = &H3FFFFFFF
  506.             LHP = VarPtr(LH(0))
  507.             LP = ArrPtr(LA)
  508.             ' safe array: Long 2
  509.             LH_(0) = 1: LH_(1) = 4: LH_(4) = &H3FFFFFFF
  510.             LHP_ = VarPtr(LH_(0))
  511.             LP_ = ArrPtr(LA_)
  512.         End If
  513.         
  514.         ' safe array: Long (first to get better speed)
  515.         PutMem4 LP, LHP
  516.         ' safe array: Long 2
  517.         LH(3) = LP_: LA(0) = LHP_
  518.         
  519.         ' prepare output byte array
  520.         z_broken_HexStringToBytes_F2 = vbNullString
  521.         ' get pointer to safe array header for manipulation
  522.         LH(3) = Not Not z_broken_HexStringToBytes_F2: Debug.Assert App.hInstance
  523.         ' calculate size of BSTR allocation
  524.         LB = (L \ 2) - 6: If LB < 0 Then LB = 0
  525.         ' create a BSTR, it works as our byte array!
  526.         LA(3) = SysAllocStringByteLen(0, LB) - 4: LA(4) = LB + 6
  527.         
  528.         ' access string via Long array 2
  529.         LH_(3) = StrPtr(Hex)
  530.         ' set long array to output data (= byte array)
  531.         LH(3) = LA(3)
  532.  
  533.         L = L \ 2
  534.  
  535.         Do
  536.             ' byte 1
  537.             For I = I To L - 1
  538.                 CH = LA_(I)
  539.                 If (CH And &HFF80FF80) = 0& Then
  540.                     CL = CH And &H7F&
  541.                     CH = (CH And &H7F0000) \ &H10000
  542.                     If CL > 47& And CL < 58& Then
  543.                         If CH > 47& And CH < 58& Then
  544.                             H = ((CH And Not 48&) * &H10&) Or (CL And Not 48&)
  545.                             Debug.Print I, VBA.Hex$(H)
  546.                             C = 1
  547.                             Exit For
  548.                         ElseIf CH > 64 And CH < 71 Then
  549.                             H = ((CH - 55&) * &H10&) Or (CL)
  550.                             C = 1
  551.                             Exit For
  552.                         End If
  553.                     ElseIf CL > 64 And CL < 71 Then
  554.                         If CH < 10 Then
  555.                             H = (CH * &H10&) Or (CL - 55&)
  556.                             C = 1
  557.                             Exit For
  558.                         ElseIf CH > 64 And CH < 71 Then
  559.                             H = ((CH - 55&) * &H10&) Or (CL - 55&)
  560.                             C = 1
  561.                             Exit For
  562.                         End If
  563.                     End If
  564.                 End If
  565.             Next I
  566.             If I + 1 < L Then I = I + 1 Else Exit Do
  567.             ' byte 2
  568.             For I = I To L - 1
  569.                 CH = LA_(I)
  570.                 If (CH And &HFF80FF80) = 0& Then
  571.                     CL = CH And &H4F&
  572.                     CH = (CH And &H4F0000) \ &H10000
  573.                     If CL < 10 Then
  574.                         If CH < 10 Then
  575.                             H = H Or (CH * &H1000&) Or (CL * &H100&)
  576.                             C = 2
  577.                             Exit For
  578.                         ElseIf CH > 64 And CH < 71 Then
  579.                             H = H Or ((CH - 55&) * &H1000&) Or (CL * &H100&)
  580.                             C = 2
  581.                             Exit For
  582.                         End If
  583.                     ElseIf CL > 64 And CL < 71 Then
  584.                         If CH < 10 Then
  585.                             H = H Or (CH * &H1000&) Or ((CL - 55&) * &H100&)
  586.                             C = 2
  587.                             Exit For
  588.                         ElseIf CH > 64 And CH < 71 Then
  589.                             H = H Or ((CH - 55&) * &H1000&) Or ((CL - 55&) * &H100&)
  590.                             C = 2
  591.                             Exit For
  592.                         End If
  593.                     End If
  594.                 End If
  595.             Next I
  596.             If I + 1 < L Then I = I + 1 Else Exit Do
  597.             ' byte 3
  598.             For I = I To L - 1
  599.                 CH = LA_(I)
  600.                 If (CH And &HFF80FF80) = 0& Then
  601.                     CL = CH And &H4F&
  602.                     CH = (CH And &H4F0000) \ &H10000
  603.                     If CL < 10 Then
  604.                         If CH < 10 Then
  605.                             H = H Or (CH * &H100000) Or (CL * &H10000)
  606.                             C = 3
  607.                             Exit For
  608.                         ElseIf CH > 64 And CH < 71 Then
  609.                             H = H Or ((CH - 55&) * &H100000) Or (CL * &H10000)
  610.                             C = 3
  611.                             Exit For
  612.                         End If
  613.                     ElseIf CL > 64 And CL < 71 Then
  614.                         If CH < 10 Then
  615.                             H = H Or (CH * &H100000) Or ((CL - 55&) * &H10000)
  616.                             C = 3
  617.                             Exit For
  618.                         ElseIf CH > 64 And CH < 71 Then
  619.                             H = H Or ((CH - 55&) * &H100000) Or ((CL - 55&) * &H10000)
  620.                             C = 3
  621.                             Exit For
  622.                         End If
  623.                     End If
  624.                 End If
  625.             Next I
  626.             If I + 1 < L Then I = I + 1 Else Exit Do
  627.             ' byte 4
  628.             For I = I To L - 1
  629.                 CH = LA_(I)
  630.                 If (CH And &HFF80FF80) = 0& Then
  631.                     CL = CH And &H4F&
  632.                     CH = (CH And &H4F0000) \ &H10000
  633.                     If CL < 10 Then
  634.                         If CH < 8 Then
  635.                             H = H Or (CH * &H10000000) Or (CL * &H1000000)
  636.                             C = 0
  637.                             Exit For
  638.                         ElseIf CH < 10 Then
  639.                             H = H Or ((CH And &H7&) * &H10000000) Or (CL * &H1000000) Or &H80000000
  640.                             C = 0
  641.                             Exit For
  642.                         ElseIf CH > 64 And CH < 71 Then
  643.                             H = H Or ((CH - 63&) * &H10000000) Or (CL * &H1000000) Or &H80000000
  644.                             C = 0
  645.                             Exit For
  646.                         End If
  647.                     ElseIf CL > 64 And CL < 71 Then
  648.                         If CH < 8 Then
  649.                             H = H Or (CH * &H10000000) Or ((CL - 55&) * &H1000000)
  650.                             C = 0
  651.                             Exit For
  652.                         ElseIf CH < 10 Then
  653.                             H = H Or ((CH And &H7&) * &H10000000) Or ((CL - 55&) * &H1000000) Or &H80000000
  654.                             C = 0
  655.                             Exit For
  656.                         ElseIf CH > 64 And CH < 71 Then
  657.                             H = H Or ((CH - 63&) * &H10000000) Or ((CL - 55&) * &H1000000) Or &H80000000
  658.                             C = 0
  659.                             Exit For
  660.                         End If
  661.                     End If
  662.                 End If
  663.             Next I
  664.             ' write
  665.             If C = 0 Then LA(J) = H: J = J + 1
  666.             ' done?
  667.             If I + 1 < L Then I = I + 1 Else Exit Do
  668.         Loop
  669.  
  670.         ' check for unwritten bytes & avoid buffer overwrite
  671.         Select Case C
  672.             Case 0
  673.             Case 1: LA(J) = (LA(J) And &HFFFFFF00) Or H
  674.             Case 2: LA(J) = (LA(J) And &HFFFF0000) Or H
  675.             Case 3: LA(J) = (LA(J) And &HFF000000) Or H
  676.         End Select
  677.         
  678.         ' calculate final length
  679.         L = J * 4 + C
  680.         Select Case L
  681.             Case LB + 6 ' do nothing!
  682.             Case 0: z_broken_HexStringToBytes_F2 = vbNullString
  683.             Case Else
  684.                 LH(3) = ArrPtr(B)
  685.                 LA(0) = Not Not z_broken_HexStringToBytes_F2: Debug.Assert App.hInstance
  686.                 ReDim Preserve B(0 To L - 1)
  687.                 LA(0) = 0
  688.         End Select
  689.  
  690.         ' safe array: Long 2
  691.         LH(3) = LP_: LA(0) = 0
  692.         ' safe array: Long
  693.         LH(3) = LP: LA(0) = 0
  694.     Else
  695.         ' empty array
  696.         z_broken_HexStringToBytes_F2 = vbNullString
  697.     End If
  698. End Function
  699.