You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB6解密函数转C#后无法兼容解密旧文件,求问题排查修复

VB6到C#解密逻辑迁移:兼容旧加密文件问题

问题背景

正在将VB6版本的文件解密逻辑迁移至C#,要求C#版本能够解密VB6版本加密的文件,但目前无法实现向后兼容。推测问题源于两种语言的类型处理、字符串操作差异。

VB6原解密代码

Public Function DecryptFile(File() As Byte) As Byte()
    Dim op1 As Integer
    Dim i As Double
    Dim j As Integer
    Dim k As Integer
    Dim l As Integer
    Dim M As Double
    Dim r As Integer
    Dim The_Password As String
    pwork = Swap(Expand_Process("Password"))
    l = Len(Trim(pwork))
    M = UBound(File)
    k = 1
    For i = 0 To M
        j = File(i) - Asc(Mid(pwork, k, 1))
        If j < 0 Then
            j = j + 256
        End If
        File(i) = j
        k = k + 1
        If k > l Then
           k = 1
        End If
    Next i
    DecryptFile = File
End Function

Public Function Swap(The_Data As String)
    Dim Y, x As Integer
    Dim rest As String
    Dim r As Integer
    Dim wrk As String
    rest = ""
    x = Len(The_Data) / 2
    For Y = 1 To x
      wrk = Mid(The_Data, Y * 2, 1) & Mid(The_Data, Y * 2 - 1, 1)
      rest = rest & wrk
    Next Y
    Y = Len(The_Data) - (x * 2)
    If Y > 0 Then
       rest = rest & Right(The_Data, Y)
    End If
    Swap = rest
End Function

Public Function Expand_Process(The_Data As String) As String
    Dim p1 As Double
    Dim p2 As Integer
    Dim rd() As Variant
    Dim m1 As Integer
    Dim m2 As Integer
    Dim dwork As String
    rd = Array(7, 3, 5, 1, 4, 2)
    p1 = Round(Len("Password") / 5, 0)
    dwork = ""
    For p2 = 1 To 5
        m1 = rd(p2) * p1
        m2 = m1 - (p1 - 1)
        dwork = dwork & Mid(The_Data, m1, p1)
    Next p2
    Expand_Process = dwork
End Function

迁移后的C#代码(存在问题)

public byte[] Decrypt(byte[] file)
{
    int op1;
    int i;
    int j;
    int k;
    int l;
    double m;
    int r;
    string pword = Swap(Expand_Process("Password"));
    l = pword.Trim().Length;
    m = file.GetUpperBound(0);
    k = 1;
    for (i = 0; i <= m; i++)
    {
        string mid = Microsoft.VisualBasic.Strings.Mid(pword, k, 1);
        int asc = Microsoft.VisualBasic.Strings.Asc(mid);
        j = file[i] - asc;
        if (j < 0)
        {
            j += 256;
        }
        file[i] = Convert.ToByte(j);
        k++;
        if (k > l)
        {
            k = 1;
        }
    }
    return file;
}

private string Expand_Process(string data)
{
    double p1;
    int[] rd;
    double m1;
    double m2;
    rd = new int[] {7, 3, 5, 1, 4, 2};
    p1 = Math.Round((double)("Password".Length / 5), 0);
    string dwork = "";
    for (int p2 = 1; p2 <= 5; p2++)
    {
        m1 = rd[p2] * p1;
        m2 = m1 - (p1 - 1);
        dwork += dwork + Microsoft.VisualBasic.Strings.Mid(data, (int)m1, (int)p1);
    }
    return dwork;
}

private string Swap(string data)
{
    int x;
    int y;
    string rest;
    int r;
    string wrk;
    rest = "";
    x = data.Length / 2;
    for (y = 1; y <= x; y++)
    {
        wrk = Microsoft.VisualBasic.Strings.Mid(data, y * 2, 1) + Microsoft.VisualBasic.Strings.Mid(data, y * 2 - 1, 1);
        rest += wrk;
    }
    y = data.Length - (x * 2);
    if (y > 0)
    {
        rest += Microsoft.VisualBasic.Strings.Right(data, y);
    }
    return rest;
}

问题排查与修复

1. Expand_Process方法的整数除法错误

VB6中Len("Password")返回8,8/5=1.6,Round(1.6,0)结果为2。但C#中"Password".Length /5是整数除法,结果为1(两个int相除会截断小数),转double后Round结果为1,与VB6逻辑不符。

修复:先将长度转为double再做除法:

p1 = Math.Round((double)"Password".Length / 5, 0);

2. Expand_Process方法的字符串拼接错误

原VB6代码中是dwork = dwork & Mid(...),即每次追加新的子串。但迁移后的C#代码写成了dwork += dwork + Mid(...),这会导致每次拼接时重复追加自身,生成错误的密码字符串。

修复:改为直接追加子串:

dwork += Microsoft.VisualBasic.Strings.Mid(data, (int)m1, (int)p1);

3. 其他潜在细节确认

  • VB6的UBound(File)与C#的file.GetUpperBound(0)行为一致,均返回数组最后一个元素的索引,循环范围正确。
  • 字节转换部分:j经过j +=256处理后范围在0-255之间,Convert.ToByte(j)是安全的,与VB6自动转换Byte的逻辑一致。
  • Swap方法中,VB6的Len(The_Data)/2赋值给Integer变量会自动取整,C#的data.Length/2(int除法)结果一致,字符串索引使用Microsoft.VisualBasic.Strings.Mid确保与VB6的1起始索引逻辑一致。

修复后的完整C#代码

public byte[] Decrypt(byte[] file)
{
    string pword = Swap(Expand_Process("Password"));
    int l = pword.Trim().Length;
    int m = file.GetUpperBound(0);
    int k = 1;
    for (int i = 0; i <= m; i++)
    {
        string mid = Microsoft.VisualBasic.Strings.Mid(pword, k, 1);
        int asc = Microsoft.VisualBasic.Strings.Asc(mid);
        int j = file[i] - asc;
        if (j < 0)
        {
            j += 256;
        }
        file[i] = Convert.ToByte(j);
        k++;
        if (k > l)
        {
            k = 1;
        }
    }
    return file;
}

private string Expand_Process(string data)
{
    int[] rd = new int[] {7, 3, 5, 1, 4, 2};
    double p1 = Math.Round((double)"Password".Length / 5, 0);
    string dwork = "";
    for (int p2 = 1; p2 <= 5; p2++)
    {
        int m1 = (int)(rd[p2] * p1);
        dwork += Microsoft.VisualBasic.Strings.Mid(data, m1, (int)p1);
    }
    return dwork;
}

private string Swap(string data)
{
    string rest = "";
    int x = data.Length / 2;
    for (int y = 1; y <= x; y++)
    {
        string wrk = Microsoft.VisualBasic.Strings.Mid(data, y * 2, 1) + Microsoft.VisualBasic.Strings.Mid(data, y * 2 - 1, 1);
        rest += wrk;
    }
    int yRemaining = data.Length - (x * 2);
    if (yRemaining > 0)
    {
        rest += Microsoft.VisualBasic.Strings.Right(data, yRemaining);
    }
    return rest;
}

内容的提问来源于stack exchange,提问作者Jesse Fogel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:15:57