⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 压缩算法.bas

📁 新魔剑压缩机。采用新的压缩算法对文件压缩。
💻 BAS
📖 第 1 页 / 共 2 页
字号:
Attribute VB_Name = "压缩算法"
Option Explicit
Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (ByRef Ptr() As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public RePlaceLim As Byte, Pro As Single, Cancel As Boolean, FileName As String

Private Type RePlaceCode
  DicCode(1 To 2) As Byte
  AscCode As Byte
End Type

Private Const ReadLen As Long = 65535

Private Function Compare(Arr() As Byte, i As Long, j As Long) As Byte
On Error GoTo Err
For Compare = 3 To 19
  If Arr(i + Compare) <> Arr(j + Compare) Then Exit Function
Next
Err:
Compare = Compare - 1
End Function


Private Sub ClearArray(Arr() As Byte, Pos As Long)
Dim t As Long
ReDim Arr(Pos To Pos)
Call CopyMemory(t, ByVal VarPtrArray(Arr), 4)
Call CopyMemory(ByVal t + 16, 0&, 4)
End Sub

Private Sub SwapArray(a() As Byte, b() As Byte)
Dim t As Long
Call CopyMemory(t, ByVal VarPtrArray(a), 4)
Call CopyMemory(ByVal VarPtrArray(a), ByVal VarPtrArray(b), 4)
Call CopyMemory(ByVal VarPtrArray(b), t, 4)
End Sub

Private Sub PointCode(SouData() As Byte, DesData() As Byte)

Const RePlaceLim As Byte = 4
Static TempData() As Byte
Static PointTable(0 To 16777215) As Long
Static i As Long, j As Long, k As Long 'i左界,j右界,k浮标
Dim PointCol(1 To 16383) As Integer 'int(65535/4)=16383
Dim PointPos As Long, DesPos As Long, TempPos As Long
Dim l As Byte, r As Byte, t As Long   'l标记
Dim RealLen As Long
Dim AscCol(0 To 255) As Boolean, AscCount As Byte

If UBound(SouData) - LBound(SouData) + 1 = 0 Then
  Erase TempData, PointTable
  i = 0
Else
  If i = 0 Then
    i = 1
    k = 1
    Call ClearArray(DesData, 1)
  End If
  ReDim Preserve TempData(i To UBound(SouData))
  Call CopyMemory(TempData(k), SouData(k), UBound(SouData) - k + 1)

  Do
    If UBound(SouData) - k + 1 > ReadLen Then RealLen = ReadLen Else RealLen = UBound(SouData) - k + 1 '确定读取大小
    j = k + RealLen - 1

    DesPos = UBound(DesData) + 1
    TempPos = DesPos

    ReDim Preserve DesData(LBound(DesData) To TempPos + RealLen + 3)
    Erase AscCol 'Asc集合

    AscCount = 255 'Asc未出现数初始化
    '确定标记l
    For t = k To j
     If AscCol(TempData(t)) = False Then '纪录Asc集合
        AscCol(TempData(t)) = True
        AscCount = AscCount - 1
      End If
      If AscCount = 0 Then Exit For
    Next
    If t < j Then j = t
    For l = 0 To 255
      If AscCol(l) = False Then Exit For
    Next
    DesData(DesPos) = l

    PointPos = 0
    DesPos = DesPos + 2

    For k = k To j - 2
      t = PointTable(TempData(k) * 65536 Or TempData(k + 1) * 256& Or TempData(k + 2))
      DesPos = DesPos + 1
      If k - t <= 4095 And t > 0 Then
        r = Compare(TempData, k, t)
        If r >= RePlaceLim Then
          PointPos = PointPos + 1
          If ((r - 4) * 4096& Or (k - t)) > 32767 Then
          PointCol(PointPos) = ((r - 4) * 4096& Or (k - t)) - 65536
          Else
          PointCol(PointPos) = (r - 4) * 4096& Or (k - t)
          End If
          DesData(DesPos) = l
          If k + r - 1 < j - 2 Then t = k + r - 1 Else t = j - 2
          For t = k To t
            PointTable(TempData(t) * 65536 Or TempData(t + 1) * 256& Or TempData(t + 2)) = t
          Next
          k = k + r - 1
        Else
          PointTable(TempData(k) * 65536 Or TempData(k + 1) * 256& Or TempData(k + 2)) = k
          DesData(DesPos) = TempData(k)
        End If
      Else
        PointTable(TempData(k) * 65536 Or TempData(k + 1) * 256& Or TempData(k + 2)) = k
        DesData(DesPos) = TempData(k)
      End If
    Next
    For k = k To j
      DesPos = DesPos + 1
      DesData(DesPos) = TempData(k)
    Next

    DesData(TempPos + 1) = (DesPos - TempPos - 2) \ 256
    DesData(TempPos + 2) = (DesPos - TempPos - 2) And &HFF
    ReDim Preserve DesData(LBound(DesData) To DesPos + 2 + 2 * PointPos)
    DesData(DesPos + 1) = PointPos \ 256
    DesData(DesPos + 2) = PointPos And &HFF
    If PointPos > 0 Then Call CopyMemory(DesData(DesPos + 3), PointCol(1), 2 * PointPos)

  Loop Until UBound(SouData) - j < 4096

  If k - 4095 > i Then i = k - 4095
  
  Call SwapArray(TempData, SouData)
  ReDim TempData(i To UBound(SouData))
  Call CopyMemory(TempData(i), SouData(i), UBound(SouData) - i + 1)
  If UBound(SouData) >= k Then
    ReDim SouData(k To UBound(SouData))
    Call CopyMemory(SouData(k), TempData(k), UBound(SouData) - k + 1)
  Else
    Call ClearArray(SouData, k)
  End If
  ReDim Preserve TempData(i To k - 1)
  
End If

End Sub

Private Sub UnPointCode(SouData() As Byte, DesData() As Byte)
'变量定义
Static TempData() As Byte
Dim PointCol(1 To 16383) As Integer 'int(65535/4)=16383
Dim RealLen As Long
Dim i As Long, j As Long, k As Long
Dim l As Byte, r As Long, t As Long
Dim PointPos As Long
Dim SouPos As Long, TempPos As Long
Dim TempData2() As Byte

SouPos = LBound(SouData)

If UBound(SouData) - LBound(SouData) + 1 = 0 Then
  Erase TempData
Else
  If LBound(SouData) = 1 Then
    Call ClearArray(DesData, 1)
    Call ClearArray(TempData, 1)
  End If


  l = SouData(SouPos)
  SouPos = SouPos + 1
  RealLen = SouData(SouPos) * 256& Or SouData(SouPos + 1)
  TempPos = SouPos + 2
  SouPos = TempPos + RealLen
  PointPos = SouData(SouPos) * 256& Or SouData(SouPos + 1)
  SouPos = SouPos + 2
  Call CopyMemory(PointCol(1), SouData(SouPos), PointPos * 2)
  SouPos = SouPos + 2 * PointPos

  j = UBound(TempData)
  ReDim Preserve TempData(LBound(TempData) To j + ReadLen) '初始化目标单元大小
  PointPos = 0
  For k = TempPos To TempPos + RealLen - 1
    j = j + 1
    If SouData(k) = l Then
      PointPos = PointPos + 1
      t = PointCol(PointPos) And &HFFF
      For r = 0 To (PointCol(PointPos) And &HFFFF&) \ 4096 + 3
        TempData(j + r) = TempData(j - t + r)
      Next
      j = j + r - 1
    Else
      TempData(j) = SouData(k)
    End If
  Next
    
  'ReDim Preserve TempData(LBound(TempData) To j)  '确定目标单元真实大小
'  ReDim Preserve DesData(LBound(DesData) To j)
'  Call CopyMemory(DesData(LBound(DesData)), TempData(LBound(DesData)), j - LBound(DesData) + 1)
  If j - 4095 > LBound(DesData) Then i = j - 4095 Else i = LBound(DesData)
  
  If SouPos > UBound(SouData) Then
    Call ClearArray(SouData, SouPos)
  Else
    ReDim TempData2(SouPos To UBound(SouData))
    Call CopyMemory(TempData2(SouPos), SouData(SouPos), UBound(SouData) - SouPos + 1)
    Call SwapArray(TempData2, SouData)
  End If

  k = LBound(DesData)
  If i < k Then
    Call SwapArray(TempData, DesData)
    ReDim TempData(i To j)
    Call CopyMemory(TempData(i), DesData(i), j - i + 1)
    ReDim DesData(k To j)
    Call CopyMemory(DesData(k), TempData(k), j - k + 1)
  Else
    If k > j Then
      Call ClearArray(DesData, k)
    Else
      ReDim DesData(k To j)
      Call CopyMemory(DesData(k), TempData(k), j - k + 1)
      ReDim TempData(i To j)
      Call CopyMemory(TempData(i), DesData(i), j - i + 1)
    End If
  End If
End If

End Sub

Private Sub RePlaceCode(SouData() As Byte, DesData() As Byte)

'变量定义
Const RePlaceLim As Byte = 20
Static RePlaceDic(1 To 255) As RePlaceCode, RePlaceAble As Byte '替换表,可替换数
Static i As Long, j As Long
Dim AscCol(0 To 255) As Boolean, AscCount As Byte 'Asc集合
Dim DicCol(0 To 65535) As Byte, DicMap(0 To 65535) As Byte '字典集合,字典映射
Dim RealLen As Long '实际流大小
Dim CycleDic(1 To 255) As RePlaceCode, CycleMap(1 To 255) As Byte '循环字典,循环映射
Dim PossibleCycle As Byte, CycleCount As Byte '可能循环字典,循环数
Dim k As Long, l As Byte, m As Long, n As Long   '杂项变量
Dim TempData() As Byte
Dim DesPos As Long

If UBound(SouData) - LBound(SouData) + 1 = 0 Then
  Erase RePlaceDic
  RePlaceAble = 0
  i = 0
Else
  If i = 0 Then
    i = 1
    Call ClearArray(DesData, 1)
  End If

  Do
    If UBound(SouData) - i + 1 > ReadLen Then RealLen = ReadLen Else RealLen = UBound(SouData) - i + 1 '确定读取大小
    DesPos = UBound(DesData)

    'DoEvents '防卡死
    '分析数据
    Erase AscCol, DicCol, DicMap 'Asc集合,字典集合,字典映射
    AscCol(SouData(i)) = True
    PossibleCycle = RePlaceAble
    RePlaceAble = 0 '可替换数初始化
    AscCount = 255 'Asc未出现数初始化
    For j = i + 1 To i + RealLen - 1
      k = SouData(j - 1) Or SouData(j) * 256&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -