delphi key解密转c# 解决string 不可变长度问题

遇见问题:

delphi的解密需要在c#里面实现

方法一:delphi编写delphi dll组件,c#里面调用
方法二:c#重写delphi的代码进行解析


方法一:

delphi部分代码:

library Project2;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes;



function UncrypStr(Src, Key: String): string;//字符串解密函数
//对字符串解密(Src:源 Key:密匙)
var KeyLen :Integer;
    KeyPos :Integer;
    offset :Integer;
    dest :string;
    SrcPos :Integer;
    SrcAsc :Integer;
    TmpSrcAsc :Integer;
begin
   KeyLen:=Length(Key);
   if KeyLen = 0 then key:='delphi';
   KeyPos:=0;
   offset:=StrToInt('$'+ copy(src,1,2));
   SrcPos:=3;
   repeat
      SrcAsc:=StrToInt('$'+ copy(src,SrcPos,2));
      if KeyPos < KeyLen
      Then KeyPos := KeyPos + 1
      else KeyPos := 1;
      TmpSrcAsc := SrcAsc xor Ord(Key[KeyPos]);
      if TmpSrcAsc <= offset
      then TmpSrcAsc := 255 + TmpSrcAsc - offset
      else TmpSrcAsc := TmpSrcAsc - offset;
      dest:=dest + chr(TmpSrcAsc);
      offset:=srcAsc;
      SrcPos:=SrcPos + 2;
   until SrcPos >= Length(Src);
   Result:=Dest;
end;
  
function filesinfo(files:string): string;stdcall;
//var
  //t:TStringlist;
  //strs:string;
  //strsss:string;
begin
    //strs:=StrPas(files);
     //t := TStringlist.Create;
      //t.LoadFromFile(strs);
      //strsss := StringReplace(UncrypStr(t.Strings[0], ''), ' ', '', [rfReplaceAll]);
       Result:=files;
end;
function Check23(AA:string):Pchar;stdcall;
var
   t:TStringlist;
   strs:string;
   begin
     t := TStringlist.Create;
     t.LoadFromFile(pchar(AA));
     strs := StringReplace(UncrypStr(t.Strings[0], ''), ' ', '', [rfReplaceAll]);
   result:=pchar(strs);
   end ;

exports
    Check23;
begin
end.


c# 调用 (如果数据量小还可以读出) 这里 的dll组建是x86的 需要把debug改成x86运行

 [DllImport(@"D:\rwas\dlls\Project2.dll", EntryPoint = "Check23")]

        static extern IntPtr Check23(string sx);

    string ss = Marshal.PtrToStringAnsi(Check23("C:\\Users\\忧郁的小学生\\Desktop\\997.azjx"));
            if (string.IsNullOrEmpty(ss)) {
                Console.WriteLine("xss");
            }

方法二:c# 重写 (刚开始用string是不可变长度,每次追加相当于开辟新的空间了,cpu占用过大,最后使用stringbuffer里面可变的)

 public string UncrypStr(string src="",string key="") {
            int KeyLen = key.Length;
             src = src.Replace("\n", "");
            src = src.Replace("\r", "");
            if (KeyLen==0) {
                key = "delphi";
            }
            int KeyPos= 0;
            int SrcAsc = 0;
            StringBuilder ps = new StringBuilder();
            string dest = "";
            int ks = 0;
            //16进制转换位10进制 delph 从起始位开始 c# 字节数组 从0开始
            string xs = src.Substring(0, 2);
            int offset = Convert.ToInt32(xs, 16);
            int SrcPos= 2;
            int TmpSrcAsc = 0;
            char[] chars = key.ToCharArray();
            while (SrcPos < (int)src.Length) {
                //截取字符串
                string tx = src.Substring(SrcPos, 2);
                //转换为16进制 将10进制转换为16进制
              SrcAsc = Convert.ToInt32(tx, 16);
                //判断解密密钥的起始
                if (KeyPos < KeyLen)
                {
                    KeyPos++;
                }
                else {
                    KeyPos = 1;
                }
                //分割成单个字符
               
                char s = chars[KeyPos-1];
                //byte[] array = System.Text.Encoding.ASCII.GetBytes(chars);

                TmpSrcAsc = SrcAsc ^ (int)s; 
                if (TmpSrcAsc <= offset)
                {
                    TmpSrcAsc = 255 + TmpSrcAsc - offset;
                }
                else
                {
                    TmpSrcAsc= TmpSrcAsc - offset;
                }
                //这里十进制直接转换ascii表不行,待转换为16进制
                //char chs = (char)TmpSrcAsc;
                string chs = TmpSrcAsc.ToString("X");

                ps.Append(chs);

                offset = SrcAsc;
                SrcPos= SrcPos + 2;
            }

            return ps.ToString();

        }
        /// <summary>
        /// ascii码转换为中文
        /// </summary>
        /// <param name="textAscii"></param>
        /// <returns></returns>
        public string getstring(string textAscii="")
        {

            string textStr = string.Empty;

            int k = 0;//字节移动偏移量

            byte[] buffer = new byte[textAscii.Length / 2];//存储变量的字节

            for (int i = 0; i < textAscii.Length / 2; i++)

            {

                //每两位合并成为一个字节

                buffer[i] = byte.Parse(textAscii.Substring(k, 2),System.Globalization.NumberStyles.HexNumber);

                k = k + 2;

            }

            //将字节转化成汉字

            textStr = Encoding.Default.GetString(buffer);

            return textStr;

        }
posted @   尘梦  阅读(287)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示
主题色彩