DES加密解密Delphi、C#互通

先上硬菜,Delphi、C#实例加解密demo下载
https://download.csdn.net/download/u011883102/86056904

 

 

C#加密解密代码

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Maticsoft.DBUtility
{

    //调用实例Demo(实现C# Dephi7互通)
    //private void button3_Click(object sender, EventArgs e)
    //{
    //    Maticsoft.DBUtility.DESEncrypt des = new Maticsoft.DBUtility.DESEncrypt();
    //    string data = textBox3.Text;
    //    string key = txtKey.Text;
    //    string iv = txtIv.Text;
    //    string xmlstr = des.EncryptDES(data, key, iv);
    //    textBox4.Text = xmlstr;
    //}
    //private void button4_Click(object sender, EventArgs e)
    //{
    //    Maticsoft.DBUtility.DESEncrypt des = new Maticsoft.DBUtility.DESEncrypt();
    //    string data = textBox4.Text;
    //    string key = txtKey.Text;
    //    string iv = txtIv.Text;
    //    string xmlstr = des.DecryptDES(data, key, iv);
    //    textBox5.Text = xmlstr;
    //}


    /// <summary>
    /// DES加密/解密类。
    /// </summary>
    public class DESEncrypt
    {
        /// <summary>  
        /// DES解密 
        /// </summary>  
        /// <param name="strEn">密文</param>  
        /// <param name="encryptKey">密钥:8位长度</param>
        /// <param name="VI">向量:8位长度</param>
        /// <returns></returns>  
        public string DecryptDES(string strEn, string encryptKey, string VI)
        {
            try
            {
                byte[] strB64 = Convert.FromBase64String(strEn);//Base64字符串转成byte数组
                string strH16 = ByteArryto16(strB64);//byte数字转成16进制字符串
                byte[] dec = Dec(strH16, encryptKey, VI);//解密
                string destring = System.Text.Encoding.GetEncoding("GB2312").GetString(dec);//byte数组转字符串
                return destring;
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="str">原文</param>
        /// <param name="encryptKey">密钥:8位长度</param>
        /// <param name="VI">向量:8位长度</param>
        /// <returns></returns>
        public string EncryptDES(string str, string encryptKey, string VI)
        {
            try
            {
                byte[] enc = Enc(str, encryptKey, VI); // 将数据Des加密,并保存到byte组
                string destring = Convert.ToBase64String(enc); //将数据转换为Base64返回
                return destring;
            }
            catch
            {
                return "";
            }
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="pToDecrypt"></param>
        /// <param name="sKey"></param>
        /// <param name="IV"></param>
        /// <returns></returns>
        private byte[] Dec(string pToDecrypt, string sKey, string IV)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
            for (int x = 0; x < pToDecrypt.Length / 2; x++)
            {
                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(IV);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            return ms.ToArray();
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="encryptString"></param>
        /// <param name="encryptKey"></param>
        /// <param name="IV"></param>
        /// <returns></returns>
        private byte[] Enc(string encryptString, string encryptKey, string IV)
        {
            byte[] rgbKey = Encoding.GetEncoding("GB2312").GetBytes(encryptKey.Substring(0, 8));
            byte[] rgbIV = Encoding.GetEncoding("GB2312").GetBytes(IV.Substring(0, 8));
            byte[] inputByteArray = Encoding.GetEncoding("GB2312").GetBytes(encryptString);
            DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return mStream.ToArray();
        }

        /// <summary>
        /// byte数组转2位16进制字符串
        /// </summary>
        /// <param name="mStreamArray"></param>
        /// <returns></returns>
        public string ByteArryto16(byte[] mStreamArray)
        {
            //--1. byte数组转2位16进制字符串
            StringBuilder ret = new StringBuilder();
            foreach (byte b in mStreamArray)
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }
        
    }
}

Delphi加密解密代码

 untDes单元

unit untDes;

//------------------------------------------------------------------------------
//调用实例Demo(实现C# Dephi7互通)
//uses
//   untBase64, untDes;
//
//procedure TForm1.btn3Click(Sender: TObject);
//var
//   data: string;
//   key: string;
//   iv: string;
//   ivArr: array[0..7] of Byte;
//begin
//   key := edtKey.Text; //一定要使用长度为8的字符
//   iv := edtIv.Text;
//   FillChar(ivArr, sizeof(ivArr), #0);
//   move(PChar(iv)^, ivArr, length(iv));
//
//   data := EncryStr(edt1.Text, key, ivArr); //Des加密
//   data := StrToBase64(data); //Base64转码
//   edt2.Text := data;
//end;
//
//procedure TForm1.btn4Click(Sender: TObject);
//var
//   data: string;
//   key: string;
//   iv: string;
//   ivArr: array[0..7] of Byte;
//begin
//   key := edtKey.Text;
//   iv := edtIv.Text;
//   FillChar(ivArr, sizeof(ivArr), #0);
//   move(PChar(iv)^, ivArr, length(iv));
//
//   data := Base64ToStr(edt2.Text); //Base64解码
//   data := DecryStrHex(data, key, ivArr); //Des解密
//   edt3.Text := data;
//end;
//------------------------------------------------------------------------------

interface

uses
   Windows, Classes, SysUtils, Dialogs;

type
   fdArray = array of dword;
   /// <summary>
   /// DES加密
   /// </summary>
   /// <param name="Str">密文</param>
   /// <param name="Key">密钥:8位长度</param>
   /// <param name="VI">向量:8位长度</param>
   /// <returns></returns>
   function EncryStr(Str, Key: string; VI: array of byte): string;
   /// <summary>
   /// DES解密
   /// </summary>
   /// <param name="Str">密文</param>
   /// <param name="Key">密钥:8位长度</param>
   /// <param name="VI">向量:8位长度</param>
   /// <returns></returns>
   function DecryStr(Str, Key: string; VI: array of byte): string;
   
   function EncryStrHex(Str, Key: string; vi: array of byte): string;
   function DecryStrHex(Str, Key: string; vi: array of byte): string;
   function des(key: string; smessage: string; encrypt: dword; mode: dword; iv: string): string;
   function des_createKeys(key: string): fdArray;
   function StrToHex(Str: string): string;
   function HexToStr(Hex: string): string;
   function IsInt(Str: string): Boolean;

implementation


function EncryStr(Str, Key: string; vi: array of byte): string;
var i: integer;
var str1: string;
var Astr: string;
begin
   for i := 0 to 7 do
   begin
      str1 := str1 + Chr(vi[i]);
   end;
   //Result := Base64.StrToBase64(des(Key, Str, 1, 1, str1));
   Result :=(des(Key, Str, 1, 1, str1));
end;

function EncryStrHex(Str, Key: string; vi: array of byte): string;
var i: integer;
var vistr: string;
begin
   for i := 0 to 7 do
   begin
      vistr := vistr + Chr(vi[i]);
   end;
   //Result := trim(StrToHex(des(Key, Str, 1, 1, vistr))); {1:加密1:CBC }  //转Hex
   Result := trim((des(Key, Str, 1, 1, vistr))); //不转Hex
   //Result := Base64.StrToBase64(Result);
end;

function DecryStr(Str, Key: string; vi: array of byte): string;
var i: integer;
var vistr: string;
begin
   for i := 0 to 7 do
   begin
      vistr := vistr + Chr(vi[i]);
   end;
   Result := trim(des(Key, Str, 0, 0, vistr));
end;

function DecryStrHex(Str, Key: string; vi: array of byte): string;
var i: integer;
var vistr: string;
begin
   for i := 0 to 7 do
   begin
      vistr := vistr + Chr(vi[i]);
   end;
   //Result := trim(des(Key, HexToStr(Str), 0, 1, vistr));  //转Hex
   Result := trim(des(Key, (Str), 0, 1, vistr));  //不转Hex
end;

function des(key: string; smessage: string; encrypt: dword; mode: dword; iv: string): string;
const
   spfunction1: array[0..63] of dword = ($1010400, 0, $10000, $1010404, $1010004, $10404, $4, $10000, $400, $1010400, $1010404, $400, $1000404, $1010004, $1000000, $4, $404, $1000400, $1000400, $10400, $10400, $1010000, $1010000, $1000404, $10004, $1000004, $1000004, $10004, 0, $404, $10404, $1000000, $10000, $1010404, $4, $1010000, $1010400, $1000000, $1000000, $400, $1010004, $10000, $10400, $1000004, $400, $4, $1000404, $10404, $1010404, $10004, $1010000, $1000404, $1000004, $404, $10404, $1010400, $404, $1000400, $1000400, 0, $10004, $10400, 0, $1010004);
   spfunction2: array[0..63] of dword = ($80108020, $80008000, $8000, $108020, $100000, $20, $80100020, $80008020, $80000020, $80108020, $80108000, $80000000, $80008000, $100000, $20, $80100020, $108000, $100020, $80008020, 0, $80000000, $8000, $108020, $80100000, $100020, $80000020, 0, $108000, $8020, $80108000, $80100000, $8020, 0, $108020, $80100020, $100000, $80008020, $80100000, $80108000, $8000, $80100000, $80008000, $20, $80108020, $108020, $20, $8000, $80000000, $8020, $80108000, $100000, $80000020, $100020, $80008020, $80000020, $100020, $108000, 0, $80008000, $8020, $80000000, $80100020, $80108020, $108000);
   spfunction3: array[0..63] of dword = ($208, $8020200, 0, $8020008, $8000200, 0, $20208, $8000200, $20008, $8000008, $8000008, $20000, $8020208, $20008, $8020000, $208, $8000000, $8, $8020200, $200, $20200, $8020000, $8020008, $20208, $8000208, $20200, $20000, $8000208, $8, $8020208, $200, $8000000, $8020200, $8000000, $20008, $208, $20000, $8020200, $8000200, 0, $200, $20008, $8020208, $8000200, $8000008, $200, 0, $8020008, $8000208, $20000, $8000000, $8020208, $8, $20208, $20200, $8000008, $8020000, $8000208, $208, $8020000, $20208, $8, $8020008, $20200);
   spfunction4: array[0..63] of dword = ($802001, $2081, $2081, $80, $802080, $800081, $800001, $2001, 0, $802000, $802000, $802081, $81, 0, $800080, $800001, $1, $2000, $800000, $802001, $80, $800000, $2001, $2080, $800081, $1, $2080, $800080, $2000, $802080, $802081, $81, $800080, $800001, $802000, $802081, $81, 0, 0, $802000, $2080, $800080, $800081, $1, $802001, $2081, $2081, $80, $802081, $81, $1, $2000, $800001, $2001, $802080, $800081, $2001, $2080, $800000, $802001, $80, $800000, $2000, $802080);
   spfunction5: array[0..63] of dword = ($100, $2080100, $2080000, $42000100, $80000, $100, $40000000, $2080000, $40080100, $80000, $2000100, $40080100, $42000100, $42080000, $80100, $40000000, $2000000, $40080000, $40080000, 0, $40000100, $42080100, $42080100, $2000100, $42080000, $40000100, 0, $42000000, $2080100, $2000000, $42000000, $80100, $80000, $42000100, $100, $2000000, $40000000, $2080000, $42000100, $40080100, $2000100, $40000000, $42080000, $2080100, $40080100, $100, $2000000, $42080000, $42080100, $80100, $42000000, $42080100, $2080000, 0, $40080000, $42000000, $80100, $2000100, $40000100, $80000, 0, $40080000, $2080100, $40000100);
   spfunction6: array[0..63] of dword = ($20000010, $20400000, $4000, $20404010, $20400000, $10, $20404010, $400000, $20004000, $404010, $400000, $20000010, $400010, $20004000, $20000000, $4010, 0, $400010, $20004010, $4000, $404000, $20004010, $10, $20400010, $20400010, 0, $404010, $20404000, $4010, $404000, $20404000, $20000000, $20004000, $10, $20400010, $404000, $20404010, $400000, $4010, $20000010, $400000, $20004000, $20000000, $4010, $20000010, $20404010, $404000, $20400000, $404010, $20404000, 0, $20400010, $10, $4000, $20400000, $404010, $4000, $400010, $20004010, 0, $20404000, $20000000, $400010, $20004010);
   spfunction7: array[0..63] of dword = ($200000, $4200002, $4000802, 0, $800, $4000802, $200802, $4200800, $4200802, $200000, 0, $4000002, $2, $4000000, $4200002, $802, $4000800, $200802, $200002, $4000800, $4000002, $4200000, $4200800, $200002, $4200000, $800, $802, $4200802, $200800, $2, $4000000, $200800, $4000000, $200800, $200000, $4000802, $4000802, $4200002, $4200002, $2, $200002, $4000000, $4000800, $200000, $4200800, $802, $200802, $4200800, $802, $4000002, $4200802, $4200000, $200800, 0, $2, $4200802, 0, $200802, $4200000, $800, $4000002, $4000800, $800, $200002);
   spfunction8: array[0..63] of dword = ($10001040, $1000, $40000, $10041040, $10000000, $10001040, $40, $10000000, $40040, $10040000, $10041040, $41000, $10041000, $41040, $1000, $40, $10040000, $10000040, $10001000, $1040, $41000, $40040, $10040040, $10041000, $1040, 0, 0, $10040040, $10000040, $10001000, $41040, $40000, $41040, $40000, $10041000, $1000, $40, $10040040, $1000, $41040, $10001000, $40, $10000040, $10040000, $10040040, $10000000, $40000, $10001040, 0, $10041040, $40040, $10000040, $10040000, $10001000, $10001040, 0, $10041040, $41000, $41000, $1040, $1040, $40040, $10000000, $10041000);
var
   keys: fdArray;
   m, i, j, k, mm: integer;
   temp, temp2, right1, right2, left, right: dword;
   looping: array of integer;
   cbcleft, cbcleft2, cbcright, cbcright2: dword;
   endloop, loopinc: integer;
   len, iterations: integer;
   chunk: integer;
   tempresult: string;
begin
   //create the 16 or 48 subkeys we will need
   keys := des_createKeys(key);
   m := 0; cbcleft := 0; cbcleft2 := 0; cbcright := 0; cbcright2 := 0; chunk := 0;
   len := length(smessage);
   //set up the loops for single and triple des
   if length(keys) = 32 then
      iterations := 3
   else
      iterations := 9;
   if iterations = 3 then
   begin
      if encrypt = 1 then
      begin
         setlength(looping, 3);
         looping[0] := 0;
         looping[1] := 32;
         looping[2] := 2;
      end
      else
      begin
         setlength(looping, 3);
         looping[0] := 30;
         looping[1] := -2;
         looping[2] := -2;
      end;
   end
   else
   begin
      if encrypt = 1 then
      begin
         setlength(looping, 9);
         looping[0] := 0;
         looping[1] := 32;
         looping[2] := 2;
         looping[3] := 62;
         looping[4] := 30;
         looping[5] := -2;
         looping[6] := 64;
         looping[7] := 96;
         looping[8] := 2;
      end
      else
      begin
         setlength(looping, 9);
         looping[0] := 94;
         looping[1] := 62;
         looping[2] := -2;
         looping[3] := 32;
         looping[4] := 64;
         looping[5] := 2;
         looping[6] := 30;
         looping[7] := -2;
         looping[8] := -2;
      end;
   end;
   //*********下面的是关键部分及对于c#补位( 待加密数据按照PKCS5规则进行补位。(缺7位补7个0x07,缺6位则补6个0x06,以次类推,如果正好8位,也需要补8个0x08)*********
   mm := 8 - Length(smessage) mod 8;
   for k := 0 to mm - 1 do
   begin
      smessage := smessage + chr(mm);
   end;
   //store the result here
   result := '';
   tempresult := '';
   if mode = 1 then //CBC mode (这里也是关键C#DES加密默认是CBC模式)
   begin
      cbcleft := (ord(iv[m + 1]) shl 24) or (ord(iv[m + 2]) shl 16) or (ord(iv[m + 3]) shl 8) or ord(iv[m + 4]);
      cbcright := (ord(iv[m + 5]) shl 24) or (ord(iv[m + 6]) shl 16) or (ord(iv[m + 7]) shl 8) or ord(iv[m + 8]);
      m := 0;
   end;
   //loop through each 64 bit chunk of the message

   if encrypt = 1 then len := Length(smessage); //(加密也和c#一样)
   while m < len do
   begin
      left := (ord(smessage[m + 1]) shl 24) or (ord(smessage[m + 2]) shl 16) or (ord(smessage[m + 3]) shl 8) or ord(smessage[m + 4]);
      right := (ord(smessage[m + 5]) shl 24) or (ord(smessage[m + 6]) shl 16) or (ord(smessage[m + 7]) shl 8) or ord(smessage[m + 8]);
      m := m + 8;
      //for Cipher Block Chaining mode, xor the message with the previous result
      if mode = 1 then
         if encrypt = 1 then
         begin
            left := left xor cbcleft;
            right := right xor cbcright;
         end
         else
         begin
            cbcleft2 := cbcleft;
            cbcright2 := cbcright;
            cbcleft := left;
            cbcright := right;
         end;
      //first each 64 but chunk of the message must be permuted according to IP
      temp := ((left shr 4) xor right) and $0F0F0F0F; right := right xor temp; left := left xor (temp shl 4);
      temp := ((left shr 16) xor right) and $0000FFFF; right := right xor temp; left := left xor (temp shl 16);
      temp := ((right shr 2) xor left) and $33333333; left := left xor temp; right := right xor (temp shl 2);
      temp := ((right shr 8) xor left) and $00FF00FF; left := left xor temp; right := right xor (temp shl 8);
      temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
      left := ((left shl 1) or (left shr 31));
      right := ((right shl 1) or (right shr 31));
      //do this either 1 or 3 times for each chunk of the message
      j := 0;
      while j < iterations do
      begin
         endloop := looping[j + 1];
         loopinc := looping[j + 2];
         //now go through and perform the encryption or decryption
         i := looping[j];
         while i <> endloop do
         begin
            right1 := right xor keys[i];
            right2 := ((right shr 4) or (right shl 28)) xor keys[i + 1];
            //the result is attained by passing these bytes through the S selection functions
            temp := left;
            left := right;
            right := temp xor (spfunction2[(right1 shr 24) and $3F] or spfunction4[(right1 shr 16) and $3F]
               or spfunction6[(right1 shr 8) and $3F] or spfunction8[right1 and $3F]
               or spfunction1[(right2 shr 24) and $3F] or spfunction3[(right2 shr 16) and $3F]
               or spfunction5[(right2 shr 8) and $3F] or spfunction7[right2 and $3F]);
            i := i + loopinc;
         end;
         temp := left; left := right; right := temp; //unreverse left and right
         j := j + 3;
      end; //for either 1 or 3 iterations
      //move then each one bit to the right
      left := ((left shr 1) or (left shl 31));
      right := ((right shr 1) or (right shl 31));
      //now perform IP-1, which is IP in the opposite direction
      temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
      temp := ((right shr 8) xor left) and $00FF00FF; left := left xor temp; right := right xor (temp shl 8);
      temp := ((right shr 2) xor left) and $33333333; left := left xor temp; right := right xor (temp shl 2);
      temp := ((left shr 16) xor right) and $0000FFFF; right := right xor temp; left := left xor (temp shl 16);
      temp := ((left shr 4) xor right) and $0F0F0F0F; right := right xor temp; left := left xor (temp shl 4);
      //for Cipher Block Chaining mode, xor the message with the previous result
      if mode = 1 then
         if encrypt = 1 then
         begin
            cbcleft := left; cbcright := right;
         end
         else
         begin
            left := left xor cbcleft2;
            right := right xor cbcright2;
         end;
      tempresult := tempresult + chr(left shr 24) + chr((left shr 16) and $FF) + chr((left shr 8) and $FF) + chr(left and $FF) + chr(right shr 24) + chr((right shr 16) and $FF) + chr((right shr 8) and $FF) + chr(right and $FF);
      chunk := chunk + 8;
      if chunk = 512 then
      begin
         result := result + tempresult; tempresult := ''; chunk := 0;
      end;
   end; //for every 8 characters, or 64 bits in the message
   //return the result as an array
   result := result + tempresult;
end; //end of des


//des_createKeys
//this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 dwords, and returns 16 48 bit keys

function des_createKeys(key: string): fdArray;
const
   //declaring this locally speeds things up a bit
   pc2bytes0: array[0..15] of dword = (0, $4, $20000000, $20000004, $10000, $10004, $20010000, $20010004, $200, $204, $20000200, $20000204, $10200, $10204, $20010200, $20010204);
   pc2bytes1: array[0..15] of dword = (0, $1, $100000, $100001, $4000000, $4000001, $4100000, $4100001, $100, $101, $100100, $100101, $4000100, $4000101, $4100100, $4100101);
   pc2bytes2: array[0..15] of dword = (0, $8, $800, $808, $1000000, $1000008, $1000800, $1000808, 0, $8, $800, $808, $1000000, $1000008, $1000800, $1000808);
   pc2bytes3: array[0..15] of dword = (0, $200000, $8000000, $8200000, $2000, $202000, $8002000, $8202000, $20000, $220000, $8020000, $8220000, $22000, $222000, $8022000, $8222000);
   pc2bytes4: array[0..15] of dword = (0, $40000, $10, $40010, 0, $40000, $10, $40010, $1000, $41000, $1010, $41010, $1000, $41000, $1010, $41010);
   pc2bytes5: array[0..15] of dword = (0, $400, $20, $420, 0, $400, $20, $420, $2000000, $2000400, $2000020, $2000420, $2000000, $2000400, $2000020, $2000420);
   pc2bytes6: array[0..15] of dword = (0, $10000000, $80000, $10080000, $2, $10000002, $80002, $10080002, 0, $10000000, $80000, $10080000, $2, $10000002, $80002, $10080002);
   pc2bytes7: array[0..15] of dword = (0, $10000, $800, $10800, $20000000, $20010000, $20000800, $20010800, $20000, $30000, $20800, $30800, $20020000, $20030000, $20020800, $20030800);
   pc2bytes8: array[0..15] of dword = (0, $40000, 0, $40000, $2, $40002, $2, $40002, $2000000, $2040000, $2000000, $2040000, $2000002, $2040002, $2000002, $2040002);
   pc2bytes9: array[0..15] of dword = (0, $10000000, $8, $10000008, 0, $10000000, $8, $10000008, $400, $10000400, $408, $10000408, $400, $10000400, $408, $10000408);
   pc2bytes10: array[0..15] of dword = (0, $20, 0, $20, $100000, $100020, $100000, $100020, $2000, $2020, $2000, $2020, $102000, $102020, $102000, $102020);
   pc2bytes11: array[0..15] of dword = (0, $1000000, $200, $1000200, $200000, $1200000, $200200, $1200200, $4000000, $5000000, $4000200, $5000200, $4200000, $5200000, $4200200, $5200200);
   pc2bytes12: array[0..15] of dword = (0, $1000, $8000000, $8001000, $80000, $81000, $8080000, $8081000, $10, $1010, $8000010, $8001010, $80010, $81010, $8080010, $8081010);
   pc2bytes13: array[0..15] of dword = (0, $4, $100, $104, 0, $4, $100, $104, $1, $5, $101, $105, $1, $5, $101, $105);
   //now define the left shifts which need to be done
   shifts: array[0..15] of dword = (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
var
   iterations: integer;
   keys: fdArray;
   lefttemp, righttemp, temp: dword;
   m, n, j, i: integer;
   left, right: dword;
begin
   //how many iterations (1 for des, 3 for triple des)
   if length(key) = 24 then
      iterations := 3
   else
      iterations := 1;
   //stores the return keys
   setlength(keys, 32 * iterations);
   //other variables
   m := 0; n := 0;
   for j := 0 to iterations - 1 do //either 1 or 3 iterations
   begin
      left := (ord(key[m + 1]) shl 24) or (ord(key[m + 2]) shl 16) or (ord(key[m + 3]) shl 8) or ord(key[m + 4]);
      right := (ord(key[m + 5]) shl 24) or (ord(key[m + 6]) shl 16) or (ord(key[m + 7]) shl 8) or ord(key[m + 8]);
      m := m + 8;
      temp := ((left shr 4) xor right) and $0F0F0F0F; right := right xor temp; left := left xor (temp shl 4);
      temp := ((right shr 16) xor left) and $0000FFFF; left := left xor temp; right := right xor (temp shl 16);
      temp := ((left shr 2) xor right) and $33333333; right := right xor temp; left := left xor (temp shl 2);
      temp := ((right shr 16) xor left) and $0000FFFF; left := left xor temp; right := right xor (temp shl 16);
      temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
      temp := ((right shr 8) xor left) and $00FF00FF; left := left xor temp; right := right xor (temp shl 8);
      temp := ((left shr 1) xor right) and $55555555; right := right xor temp; left := left xor (temp shl 1);
      //the right side needs to be shifted and to get the last four bits of the left side
      temp := (left shl 8) or ((right shr 20) and $000000F0);
      //left needs to be put upside down
      left := (right shl 24) or ((right shl 8) and $FF0000) or ((right shr 8) and $FF00) or ((right shr 24) and $F0);
      right := temp;
      //now go through and perform these shifts on the left and right keys
      for i := low(shifts) to high(shifts) do
      begin
         //shift the keys either one or two bits to the left
         if shifts[i] > 0 then
         begin
            left := (left shl 2) or (left shr 26);
            right := (right shl 2) or (right shr 26);
            //left := left shl 0;
            //right:= right shl 0;
         end
         else
         begin
            left := (left shl 1) or (left shr 27);
            right := (right shl 1) or (right shr 27);
            //left := left shl 0;
            //right:= right shl 0;
         end;
         left := left and $FFFFFFF0;
         right := right and $FFFFFFF0;
         //now apply PC-2, in such a way that E is easier when encrypting or decrypting
         //this conversion will look like PC-2 except only the last 6 bits of each byte are used
         //rather than 48 consecutive bits and the order of lines will be according to
         //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
         lefttemp := pc2bytes0[left shr 28] or pc2bytes1[(left shr 24) and $F]
            or pc2bytes2[(left shr 20) and $F] or pc2bytes3[(left shr 16) and $F]
            or pc2bytes4[(left shr 12) and $F] or pc2bytes5[(left shr 8) and $F]
            or pc2bytes6[(left shr 4) and $F];
         righttemp := pc2bytes7[right shr 28] or pc2bytes8[(right shr 24) and $F]
            or pc2bytes9[(right shr 20) and $F] or pc2bytes10[(right shr 16) and $F]
            or pc2bytes11[(right shr 12) and $F] or pc2bytes12[(right shr 8) and $F]
            or pc2bytes13[(right shr 4) and $F];
         temp := ((righttemp shr 16) xor lefttemp) and $0000FFFF;
         keys[n + 0] := lefttemp xor temp;
         keys[n + 1] := righttemp xor (temp shl 16);
         n := n + 2;
      end;
   end; //for each iterations
   //return the keys we've created
   Result := keys;
end; //end of des_createKeys


function StrToHex(Str: string): string;
var
   i: integer;
begin
   result := '';
   for i := 1 to length(Str) do
      result := result + IntToHex(Ord(Str[i]), 2);
end;

function HexToStr(Hex: string): string;
var
   i: Integer;
begin
   Result := '';
   for i := 1 to length(Hex) div 2 do
      if IsInt('$' + Hex[i * 2 - 1] + Hex[i * 2]) then
         Result := Result + Chr(StrToInt('$' + Hex[i * 2 - 1] + Hex[i * 2]));
end;

function IsInt(Str: string): Boolean;
begin
   result := True;
   try
      StrToInt(Str);
   except
      result := False
   end;
end;


{function EncryStr_3DES(Str, Key: String): String;
var s  ,StrResult, TempResult, Temp: String;
 I: Integer;
begin
  if Length(Key) < 16 then
    while Length(Key) < 16 do
      Key := Key + Chr(0);
   s := EncryStrHex(Str, Copy(Key, 1, 8));
   s := DecryStrHex(s, Copy(Key, 9, 8));
   s := EncryStrHex(s, Copy(Key, 1, 8));
      Result := s;
end;  }

end.

 untBase64单元


unit untBase64;

interface

uses SysUtils, Classes;

type
{$IFDEF UNICODE}
  Base64String = AnsiString;
{$ELSE}
  Base64String = string;
{$ENDIF}

// 按源长度SourceSize返回Base64编码所需缓冲区字节数
function Base64EncodeBufSize(SourceSize: Integer): Integer;
// 获取Sourec的Base64编码,Base64Buf必须有足够长度。返回实际编码字节数
function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer; overload;
// 将Source编码为Base64字符串返回
function Base64Encode(const Source; SourceSize: Integer): Base64String; overload;
// 将Source从StartPos开始的Size长度的内容源编码为Base64,写入流Dest。
// Size=0 表示一直编码到文件尾
procedure Base64Encode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
// 把字符串Str编码为Base64字符串返回
{$IFDEF UNICODE}
function StrToBase64(const Str: AnsiString): Base64String; overload;
function StrToBase64(const Str: string): Base64String; overload;
{$ELSE}
function StrToBase64(const Str: string): Base64String;
{$ENDIF}

// 按给定的编码源Source和长度SourceSize计算并返回解码缓冲区所需字节数
function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
// 将Base64编码源Base64Source解码,Buf必须有足够长度。返回实际解码字节数
function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer; overload;
// 将Source从StartPos开始的Size长度的Base64编码内容解码,写入流Dest。
// Size=0 表示一直解码到文件尾
procedure Base64Decode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
// 将Base64编码源Base64Source解码为字符串返回
function Base64Decode(const Base64Source; SourceSize: Integer): string; overload;
// 把Base64字符串Base64Str解码为字符串返回
function Base64ToStr(const Base64Str: Base64String): string;

implementation

const
  Base64_Chars: array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  Base64_Bytes: array[0..79] of Byte =
  (
    62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
    0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
    36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
  );
  
type
  Base64Proc = function(const Source; SourceSize: Integer; var Buf): Integer;

procedure Base64Stream(Source, Dest: TStream; Proc: Base64Proc;
  StartPos, Size: Int64; RBufSize, WBufSize: Integer);
var
  RBuf: array of Byte;
  WBuf: array of Byte;
  RSize, WSize: Integer;
begin
  if (StartPos < 0) or (StartPos >= Source.Size) then Exit;
  Source.Position := StartPos;
  if (Size <= 0) or (Size > Source.Size - Source.Position) then
    Size := Source.Size
  else
    Size := Size + Source.Position;
  SetLength(RBuf, RBufSize);
  SetLength(WBuf, WBufSize);
  while Size <> Source.Position do
  begin
    if RBufSize > Size - Source.Position then
       RBufSize := Size - Source.Position;
    RSize := Source.Read(RBuf[0], RBufSize);
    WSize := Proc(RBuf[0],  RSize, WBuf[0]);
    Dest.Write(WBuf[0], WSize);
  end;
end;

function Base64EncodeBufSize(SourceSize: Integer): Integer;
begin
  Result := ((SourceSize + 2) div 3) shl 2;
end;

(****************************************************************************
*                                                                           *
* BASE64 Encode hint:                                                       *
*                                                                           *
* addr:            (high) 4 byte     3 byte     2 byte     1 byte (low)     *
* sourec ASCII(3 bytes):            33333333   22222222   11111111          *
* bswap:                 11111111   22222222   33333333   00000000          *
* b4 = Base64_Chars[(source >> 8) & 63]:      [00333333]->44444444          *
* b3 = Base64_Chars[(source >> 14) & 63]:     [00222233]->33333333          *
* b2 = Base64_Chars[(source >> 20) & 63]:     [00112222]->22222222          *
* b1 = Base64_Chars[source >> 26]:            [00111111]->11111111          *
*                        b4 << 24   b3 << 16   b2 << 8    b1                *
* dest BASE64(4 bytes)   44444444   33333333   22222222   11111111          *
*                                                                           *
****************************************************************************)

function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer;
asm
    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax         // esi = Source
    mov     edi, ecx         // edi = Buf
    mov     eax, edx
    cdq
    mov     ecx, 3
    div     ecx              // edx = SourceSize % 3
    mov     ecx, eax         // ecx = SourceSize / 3
    test    edx, edx         
    jz      @@1
    inc     eax              // eax = (SourceSize + 2) / 3
  @@1:
    push    eax
    push    edx
    lea     ebp, Base64_Chars
    jecxz   @Last
    cld
  @EncodeLoop:               //  while (ecx > 0){
    mov     edx, [esi]       //   edx = 00000000 33333333 22222222 11111111
    bswap   edx              //   edx = 11111111 22222222 33333333 00000000
    push    edx
    push    edx
    push    edx
    pop     ebx              //   ebx = edx
    shr     edx, 20
    shr     ebx, 26          //   ebx = 00111111
    and     edx, 63          //   edx = 00112222
    mov     ah, [ebp + edx]  //   *(word*)edi = (Base64_Chars[edx] << 8) |
    mov     al, [ebp + ebx]  //     Base64_Chars[ebx]
    stosw                    //   edi += 2
    pop     edx              //   edx = 11111111 22222222 33333333 00000000
    pop     ebx              //   ebx = edx
    shr     edx, 8
    shr     ebx, 14
    and     edx, 63          //   edx = 00333333
    and     ebx, 63          //   ebx = 00222233
    mov     ah, [ebp + edx]  //   *(word*)edi = (Base64_Chars[edx] << 8) |
    mov     al, [ebp + ebx]  //     Base64_Chars[ebx]
    stosw                    //   edi += 2
    add     esi, 3           //   esi += 3
    loop    @EncodeLoop      // }
  @Last:
    pop     ecx              // ecx = SourceSize % 3
    jecxz   @end             // if (ecx == 0) return
    mov     eax, 3d3d0000h   // preset 2 bytes '='
    mov     [edi], eax
    test    ecx, 2
    jnz     @@3
    mov     al, [esi]        // if (ecx == 1)
    shl     eax, 4           //   eax = *esi << 4
    jmp     @@4
  @@3:
    mov     ax, [esi]        // else
    xchg    al, ah           //   eax = ((*esi << 8) or *(esi + 1)) << 2
    shl     eax, 2
  @@4:
    add     edi, ecx         // edi += ecx
    inc     ecx              // ecx = last encode bytes
  @LastLoop:
    mov     edx, eax         // for (; cex > 0; ecx --, edi --)
    and     edx, 63          // {
    mov     dl, [ebp + edx]  //   edx = eax & 63
    mov     [edi], dl        //   *edi = Base64_Chars[edx]
    shr     eax, 6           //   eax >>= 6
    dec     edi              // }
    loop    @LastLoop
  @end:
    pop     eax
    shl     eax, 2           // return  encode bytes
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
end;

function Base64Encode(const Source; SourceSize: Integer): Base64String;
begin
  SetLength(Result, Base64EncodeBufSize(SourceSize));
  Base64Encode(Source, SourceSize, Result[1]);
end;

procedure Base64Encode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
begin
  Base64Stream(Source, Dest, Base64Encode, StartPos, Size, 6144, 8192);
end;

{$IFDEF UNICODE}
function StrToBase64(const Str: AnsiString): Base64String;
begin
  Result := Base64Encode(Str[1], Length(Str));
end;

function StrToBase64(const Str: string): Base64String;
begin
  Result := StrToBase64(AnsiString(Str));
end;
{$ELSE}
function StrToBase64(const Str: string): Base64String;
begin
  Result := Base64Encode(Str[1], Length(Str));
end;
{$ENDIF}

function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
asm
    mov     ecx, eax    // ecx = Source + Size
    add     ecx, edx
    mov     eax, edx    // eax = Size / 4 * 3
    shr     edx, 2
    shr     eax, 1
    add     eax, edx
    mov     edx, eax
    jz      @@2
  @@1:
    dec     ecx
    cmp     byte ptr [ecx], 61
    jne     @@2         // if (*--ecx == '=')
    dec     eax         //   eax --
    jmp     @@1
  @@2:                  // return eax: BufSize;  edx: Size / 4 * 3
end;

function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer;
asm
    push    ebp
    push    esi
    push    edi
    push    ebx
    mov     esi, eax       // esi = Source
    mov     edi, ecx       // edi = Buf
    mov     ebx, edx
    call    Base64DecodeBufSize
    push    eax            // eax = Base64DecodeBufSize(Source, SourceSize)
    sub     edx, eax       // edx -= eax  // edx: '=' count
    lea     ebp, Base64_Bytes
    shr     ebx, 2         // ebx = SourceSize / 4
    test    ebx, ebx
    jz      @end
    push    edx
    cld
  @DecodeLoop:             // for (; ebx > 0; ebx --; edi += 3)
    mov     ecx, 4         // {
    xor     eax, eax
  @xchgLoop:               //   for (ecx = 4, eax = 0; ecx > 0; ecx --)
    movzx   edx, [esi]     //   {
    sub     edx, 43        //      edx = *(int*)esi - 43
    shl     eax, 6         //      eax <<= 6
    or      al, [ebp + edx]//      al |= Base64_Bytes[edx]
    inc     esi            //      esi ++
    loop    @xchgLoop      //   }
    bswap   eax            //   bswap(eax)
    dec     ebx            //   if (ebx == 1) break
    jz      @Last
    shr     eax, 8         //   eax >>= 8
    stosw                  //   *edi = ax; edi += 2
    shr     eax, 16        //   eax >>= 16
    stosb                  //   *edi++ = al
    jmp     @DecodeLoop    // }
  @Last:
    pop     ecx            
    xor     ecx, 3         // ecx = last bytes
  @LastLoop:               // for (; ecx > 0; ecx --)
    shr     eax, 8         // {
    stosb                  //   eax >>= 8; *edi ++ = al
    loop    @LastLoop      // }
  @end:
    pop     eax            // return eax
    pop     ebx
    pop     edi
    pop     esi
    pop     ebp
end;

procedure Base64Decode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
begin
  Base64Stream(Source, Dest, Base64Decode, StartPos, Size, 8192, 6144);
end;

{$IFDEF UNICODE}
function Base64Decode(const Base64Source; SourceSize: Integer): string;
var
  s: AnsiString;
begin
  SetLength(s, Base64DecodeBufSize(Base64Source, SourceSize));
  Base64Decode(Base64Source, SourceSize, s[1]);
  Result := string(s);
end;
{$ELSE}
function Base64Decode(const Base64Source; SourceSize: Integer): string;
begin
  SetLength(Result, Base64DecodeBufSize(Base64Source, SourceSize));
  Base64Decode(Base64Source, SourceSize, Result[1]);
end;
{$ENDIF}

function Base64ToStr(const Base64Str: Base64String): string;
begin
  Result := Base64Decode(Base64Str[1], Length(Base64Str));
end;

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值