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 @ 2019-11-25 14:27  尘梦  阅读(285)  评论(0编辑  收藏  举报