先上硬菜,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.