一个DELPHI写的DES算法,哪位帮忙翻译成C#,分数好说~

espnstar 2005-07-26 06:42:12
unit Des;

interface

uses SysUtils;

type
TKeyByte = array[0..5] of Byte;
TDesMode = (dmEncry, dmDecry);

function EncryStr(Str, Key: String): String;
function DecryStr(Str, Key: String): String;
function EncryStrHex(Str, Key: String): String;
function DecryStrHex(StrHex, Key: String): String;

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

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

BitExp: array[0..47] of Integer =
( 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31,0 );

BitPM: array[0..31] of Byte =
( 15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24 );

sBox: array[0..7] of array[0..63] of Byte =
( ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 ),

( 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 ),

( 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ),

( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 ),

( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 ),

( 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 ),

( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 ),

( 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ) );

BitPMC1: array[0..55] of Byte =
( 56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3 );

BitPMC2: array[0..47] of Byte =
( 13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31 );

var
subKey: array[0..15] of TKeyByte;

implementation

procedure initPermutation(var inData: array of Byte);
var
newData: array[0..7] of Byte;
i: Integer;
begin
FillChar(newData, 8, 0);
for i := 0 to 63 do
if (inData[BitIP[i] shr 3] and (1 shl (7- (BitIP[i] and $07)))) <> 0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
for i := 0 to 7 do inData[i] := newData[i];
end;

procedure conversePermutation(var inData: array of Byte);
var
newData: array[0..7] of Byte;
i: Integer;
begin
FillChar(newData, 8, 0);
for i := 0 to 63 do
if (inData[BitCP[i] shr 3] and (1 shl (7-(BitCP[i] and $07)))) <> 0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
for i := 0 to 7 do inData[i] := newData[i];
end;

procedure expand(inData: array of Byte; var outData: array of Byte);
var
i: Integer;
begin
FillChar(outData, 6, 0);
for i := 0 to 47 do
if (inData[BitExp[i] shr 3] and (1 shl (7-(BitExp[i] and $07)))) <> 0 then
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));
end;

procedure permutation(var inData: array of Byte);
var
newData: array[0..3] of Byte;
i: Integer;
begin
FillChar(newData, 4, 0);
for i := 0 to 31 do
if (inData[BitPM[i] shr 3] and (1 shl (7-(BitPM[i] and $07)))) <> 0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)));
for i := 0 to 3 do inData[i] := newData[i];
end;

function si(s,inByte: Byte): Byte;
var
c: Byte;
begin
c := (inByte and $20) or ((inByte and $1e) shr 1) or
((inByte and $01) shl 4);
Result := (sBox[s][c] and $0f);
end;

procedure permutationChoose1(inData: array of Byte;
var outData: array of Byte);
var
i: Integer;
begin
FillChar(outData, 7, 0);
for i := 0 to 55 do
if (inData[BitPMC1[i] shr 3] and (1 shl (7-(BitPMC1[i] and $07)))) <> 0 then
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)));
end;
...全文
844 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
dragonimp 2006-06-05
  • 打赏
  • 举报
回复
.NET带的那个类加密结果是要多8个字节(如果转16进制字符就是16个了)
而DES本身来说好像就是多少进多少出,位数不变.
这个贴子的delphi实现是没有增加字节的.可能跟IV有关,没认真看.
不知道哪个是标准的.
bflovesnow 2005-09-19
  • 打赏
  • 举报
回复
hehe,弓虽!
我不懂电脑 2005-09-19
  • 打赏
  • 举报
回复
.net本身就提供了des加密类。不需要自己做。

DES 类请参见
DES 成员 | System.Security.Cryptography 命名空间 | 加密服务 | DES 成员(Visual J# 语法) | C++ 托管扩展编程
要求
命名空间: System.Security.Cryptography

表示所有 DES 实现都必须从中派生的数据加密标准 (DES) 算法的基类。

有关此类型所有成员的列表,请参阅 DES 成员。

wuyi8808 2005-09-18
  • 打赏
  • 举报
回复
zgb(sky)兄中秋快乐!

public string EncryStr(string Str, string Key)
public string DecryStr(string Str, string Key)

我想Delphi的String是单字节的, 应该是等同于C#的byte[], 严格来说,

function EncryStr(Str, Key: String): String;
function DecryStr(Str, Key: String): String;

翻译成C#应该是:

public string EncryStr(byte [] Str, byte [] Key)
public string DecryStr(byte [] Str, byte [] Key)

当然, 函数体也要作相应改动.

------------------------------------------------------------------

zgb(sky)兄很细心, 注意到这个程序不支持中文. 我也已经注意到这个问题, 在以下贴子中有如下说明:
http://community.csdn.net/Expert/topic/4273/4273839.xml
注意, 这个程序仅支持对ascii字符串的加解密, 本质上是对 byte[] 进行加解密, 若要使用含中文等宽字符的unicode字符串, 请先转换为utf8之类的的单字码, 再传递给EncryStr()等函数, 否则解密出来的结果可能不正确.

谢谢zgb(sky)兄对程序的完善. 最好把以下函数中的Default明确指定为UTF8,
System.Text.Encoding.Default.GetBytes()
System.Text.Encoding.Default.GetString()
以免因不同机器上的Default编码有所不同而导致加解密不一致.
zgb 2005-09-18
  • 打赏
  • 举报
回复
wuyi8808(tm) studio   :) 你好厉害哟!万分感谢!
祝中秋节快乐!!!
楼主不是我,如果需要我重开个帖子给你加分。
zgb 2005-09-18
  • 打赏
  • 举报
回复
支持汉字:
public string EncryStr(string Str, string Key)
{
byte [] StrByte = new byte [8];
byte [] OutByte = new byte [8];
byte [] KeyByte = new byte [8];

byte[] sByte = System.Text.Encoding.Default.GetBytes(Str);
int sLen = sByte.Length;


if ((sLen > 0) && (sByte[sLen-1] == 0))
{
throw new ArgumentException("Error: the last char is NULL char.", "Str");
}
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
while (sLen % 8 != 0)
{
Str += '\0';
sByte = System.Text.Encoding.Default.GetBytes(Str);
sLen = sByte.Length;
}
for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);

StringBuilder StrResult = new StringBuilder();

for (int i = 0; i < sLen / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = sByte[i * 8 + j];
}
desData(TDesMode.dmEncry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};

return StrResult.ToString();
}

public string DecryStr(string Str, string Key)
{
byte [] StrByte = new byte [8];
byte [] OutByte = new byte [8];
byte [] KeyByte = new byte [8];
byte [] StrRst = new byte [Str.Length];

if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}

for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);

StringBuilder StrResult = new StringBuilder();

int ii = 0;
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmDecry, StrByte, OutByte);


for (int j = 0; j < 8; j++)
{
StrRst[ii] = OutByte[j];
ii++;
}
};

string StrR = System.Text.Encoding.Default.GetString(StrRst);
int ioo = StrR.Length;
return StrR.TrimEnd('\0');
}

conan19771130 2005-09-18
  • 打赏
  • 举报
回复
楼主揭帖啊
wuyi8808 2005-09-14
  • 打赏
  • 举报
回复
// 翻译了开头的一部分, 夜了, 睡觉先...

namespace Delphi
{
using System;

class TKeyByte
{
public byte [] value = new byte [6];
}

enum TDesMode { dmEncry, dmDecry };

class Des
{
static readonly byte [] BitIP =
{
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6
};

static readonly byte [] BitCP =
{
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
32, 0, 40, 8, 48, 16, 56, 24
};

static readonly int [] BitExp =
{
31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0
};

static readonly byte [] BitPM =
{
15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24
};

static readonly byte [,] sBox =
{
{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
},
{
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
},
{
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
},
{
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
},
{
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
},
{
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
},
{
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
},
{
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}
};

static readonly byte [] BitPMC1 =
{
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};

static readonly byte [] BitPMC2 =
{
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31
};

TKeyByte [] subKey = new TKeyByte [16];

void initPermutation(byte [] inData)
{
byte [] newData = new byte [8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}

void conversePermutation(byte [] inData)
{
byte [] newData = new byte [8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}

void expand(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

void permutation(byte [] inData)
{
byte [] newData = new byte [4];
for (int i = 0; i < 32; i++)
{
if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 4);
}

byte si(byte s, byte inByte)
{
int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);
return (byte)(sBox[s,c] & 0x0f);
}

void permutationChoose1(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 7);
for (int i = 0; i < 56; i++)
{
if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

void permutationChoose2(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

// 未完, 待续...

} // End of class Des
} // End of namespace Delphi
wuyi8808 2005-09-14
  • 打赏
  • 举报
回复
function EncryStr(Str, Key: String): String;
begin
if (Length(Str) > 0) and (Ord(Str[Length(Str)]) = 0) then
raise Exception.Create('Error: the last char is NULL char.');
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1]);
end;

看看上述语句, 似乎在Delphi中, String的下标是从 1 到 Length(String), 而不是从 0 到 Length(String)-1. 我很多年没接触Pascal语言了, 不知关于String的下标的理解正确否. 如果我的理解正确的话, 上述程序段翻译成C#就是这样的:

string EncryStr(string Str, string Key)
{
if ((Str.Length > 0) && (Str[Str.Length-1] == 0))
{
throw new ArgumentException("Error: the last char is NULL char.", "Str");
}
for (int J = 0; J < 8; J++) KeyByte[J] = (byte)Key[J]; // 不是 Key[J + 1] ?
}
wuyi8808 2005-09-14
  • 打赏
  • 举报
回复
namespace Skyiv
{
using System;

class Test
{
static void Main()
{
DelphiDes des = new DelphiDes();
string key = "the KEY";
string s0 = "This is a test for Delphi.Des";
Console.WriteLine("原串: [{0}]", s0);
string s1 = des.EncryStr(s0, key);
Console.WriteLine("加密: [{0}]", s1);
string s2 = des.DecryStr(s1, key);
Console.WriteLine("解密: [{0}]", s2);
string s3 = des.EncryStrHex(s0, key);
Console.WriteLine("HEX : [{0}]", s3);
string s4 = des.DecryStrHex(s3, key);
Console.WriteLine("解密: [{0}]", s4);
}
} // End of class Test
} // End of namespace Skyiv

/* 程序输出:
原串: [This is a test for Delphi.Des]
加密: [??&6YV?ròv8c/y{?é(ó}??-k¤h?¤']
解密: [This is a test for Delphi.Des]
HEX : [BDF6263659560B911172D27638632F12FD7B83E928D37D94B6AD6BA468DBA427]
解密: [This is a test for Delphi.Des]
*/
wuyi8808 2005-09-14
  • 打赏
  • 举报
回复
static readonly byte [] bitDisplace = { 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 };

void makeKey(byte [] inKey, byte [][] outKey)
{
byte [] outData56 = new byte [7];
byte [] key28l = new byte [4];
byte [] key28r = new byte [4];
byte [] key56o = new byte [7];

permutationChoose1(inKey, outData56);
key28l[0] = (byte)(outData56[0] >> 4);
key28l[1] = (byte)((outData56[0] << 4) | (outData56[1] >> 4));
key28l[2] = (byte)((outData56[1] << 4) | (outData56[2] >> 4));
key28l[3] = (byte)((outData56[2] << 4) | (outData56[3] >> 4));
key28r[0] = (byte)(outData56[3] & 0x0f);
key28r[1] = (byte)(outData56[4]);
key28r[2] = (byte)(outData56[5]);
key28r[3] = (byte)(outData56[6]);

for (int i = 0; i < 16; i++)
{
cycleMove(key28l, bitDisplace[i]);
cycleMove(key28r, bitDisplace[i]);
key56o[0] = (byte)((key28l[0] << 4) | (key28l[1] >> 4));
key56o[1] = (byte)((key28l[1] << 4) | (key28l[2] >> 4));
key56o[2] = (byte)((key28l[2] << 4) | (key28l[3] >> 4));
key56o[3] = (byte)((key28l[3] << 4) | (key28r[0]));
key56o[4] = (byte)(key28r[1]);
key56o[5] = (byte)(key28r[2]);
key56o[6] = (byte)(key28r[3]);
permutationChoose2(key56o, outKey[i]);
};
}

void encry(byte [] inData, byte [] subKey, byte [] outData)
{
byte [] outBuf = new byte [6];
byte [] buf = new byte [8];

expand(inData, outBuf);
for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
buf[0] = (byte)(outBuf[0] >> 2); //xxxxxx -> 2
buf[1] = (byte)(((outBuf[0] & 0x03) << 4) | (outBuf[1] >> 4)); // 4 <- xx xxxx -> 4
buf[2] = (byte)(((outBuf[1] & 0x0f) << 2) | (outBuf[2] >> 6)); // 2 <- xxxx xx -> 6
buf[3] = (byte)(outBuf[2] & 0x3f); // xxxxxx
buf[4] = (byte)(outBuf[3] >> 2); // xxxxxx
buf[5] = (byte)(((outBuf[3] & 0x03) << 4) | (outBuf[4] >> 4)); // xx xxxx
buf[6] = (byte)(((outBuf[4] & 0x0f) << 2) | (outBuf[5] >> 6)); // xxxx xx
buf[7] = (byte)(outBuf[5] & 0x3f); // xxxxxx
for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);
for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i*2] << 4) | buf[i*2+1]);
permutation(outBuf);
for (int i = 0; i < 4; i++) outData[i] = outBuf[i];
}

// inData, outData 都为 8 Bytes,否则出错
void desData(TDesMode desMode, byte [] inData, byte [] outData)
{
int i, j;
byte [] temp = new byte [4];
byte [] buf = new byte [4];

for (i = 0; i < 8; i++) outData[i] = inData[i];
initPermutation(outData);
if (desMode == TDesMode.dmEncry)
{
for (i = 0; i < 16; i++)
{
for (j = 0; j < 4; j++) temp[j] = outData[j]; //temp = Ln
for (j = 0; j < 4; j++) outData[j] = outData[j+4]; //Ln+1 = Rn
encry(outData, SubKey[i], buf); //Rn ==Kn==> buf
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]); //Rn+1 = Ln^buf
};
for (j = 0; j < 4; j++) temp[j] = outData[j+4];
for (j = 0; j < 4; j++) outData[j+4] = outData[j];
for (j = 0; j < 4; j++) outData[j] = temp[j];
}
else if (desMode == TDesMode.dmDecry)
{
for (i = 15; i >= 0; i--)
{
for (j = 0; j < 4; j++) temp[j] = outData[j];
for (j = 0; j < 4; j++) outData[j] = outData[j+4];
encry(outData, SubKey[i], buf);
for (j = 0; j < 4; j++) outData[j+4] = (byte)(temp[j] ^ buf[j]);
};
for (j = 0; j < 4; j++) temp[j] = outData[j+4];
for (j = 0; j < 4; j++) outData[j+4] = outData[j];
for (j = 0; j < 4; j++) outData[j] = temp[j];
};
conversePermutation(outData);
}

//////////////////////////////////////////////////////////////

public string EncryStr(string Str, string Key)
{
byte [] StrByte = new byte [8];
byte [] OutByte = new byte [8];
byte [] KeyByte = new byte [8];

if ((Str.Length > 0) && (Str[Str.Length-1] == 0))
{
throw new ArgumentException("Error: the last char is NULL char.", "Str");
}
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
while (Str.Length % 8 != 0) Str += '\0';

for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);

StringBuilder StrResult = new StringBuilder();
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmEncry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};

return StrResult.ToString();
}

public string DecryStr(string Str, string Key)
{
byte [] StrByte = new byte [8];
byte [] OutByte = new byte [8];
byte [] KeyByte = new byte [8];

if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}

for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);

StringBuilder StrResult = new StringBuilder();
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmDecry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};

return StrResult.ToString().TrimEnd('\0');
}

//////////////////////////////////////////////////////////////

public string EncryStrHex(string Str, string Key)
{
string TempResult = EncryStr(Str, Key);
StringBuilder StrResult = new StringBuilder();
foreach (char c in TempResult)
{
StrResult.AppendFormat("{0:X2}", (int)c);
}
return StrResult.ToString();
}

public string DecryStrHex(string StrHex, string Key)
{
if (StrHex.Length % 2 != 0)
{
throw new ArgumentException("Error: string length must be even.", "StrHex");
}
StringBuilder Str = new StringBuilder();
for (int i = 0; i < StrHex.Length; i += 2)
{
Str.Append((char)(Uri.FromHex(StrHex[i])*16 + Uri.FromHex(StrHex[i+1])));
}
return DecryStr(Str.ToString(), Key);
}
} // End of class DelPhiDes
} // End of namespace Skyiv
wuyi8808 2005-09-14
  • 打赏
  • 举报
回复
// 一个Delphi写的DES算法, 翻译成C#, 2005.09.14

namespace Skyiv
{
using System;
using System.Text;

enum TDesMode { dmEncry, dmDecry };

class DelphiDes
{
static readonly byte [] BitIP =
{
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6
};

static readonly byte [] BitCP =
{
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
32, 0, 40, 8, 48, 16, 56, 24
};

static readonly int [] BitExp =
{
31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0
};

static readonly byte [] BitPM =
{
15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24
};

static readonly byte [,] sBox =
{
{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
},
{
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
},
{
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
},
{
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
},
{
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
},
{
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
},
{
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
},
{
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}
};

static readonly byte [] BitPMC1 =
{
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};

static readonly byte [] BitPMC2 =
{
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31
};

byte [][] SubKey;

public DelphiDes()
{
SubKey = new byte [16][];
for (int i = 0; i < SubKey.Length; i++)
{
SubKey[i] = new byte [6];
}
}

void initPermutation(byte [] inData)
{
byte [] newData = new byte [8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}

void conversePermutation(byte [] inData)
{
byte [] newData = new byte [8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}

void expand(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

void permutation(byte [] inData)
{
byte [] newData = new byte [4];
for (int i = 0; i < 32; i++)
{
if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 4);
}

byte si(byte s, byte inByte)
{
int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);
return (byte)(sBox[s,c] & 0x0f);
}

void permutationChoose1(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 7);
for (int i = 0; i < 56; i++)
{
if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

void permutationChoose2(byte [] inData, byte [] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}

void cycleMove(byte [] inData, byte bitMove)
{
for (int i = 0; i < bitMove; i++)
{
inData[0] = (byte)((inData[0] << 1) | (inData[1] >> 7));
inData[1] = (byte)((inData[1] << 1) | (inData[2] >> 7));
inData[2] = (byte)((inData[2] << 1) | (inData[3] >> 7));
inData[3] = (byte)((inData[3] << 1) | ((inData[0] & 0x10) >> 4));
inData[0] = (byte)(inData[0] & 0x0f);
}
}
zgb 2005-09-12
  • 打赏
  • 举报
回复
好,谢谢!
wuyi8808 2005-09-12
  • 打赏
  • 举报
回复
哦,那只有把你的 Delphi 程序翻译成 C# 程序了。等我有空时帮你看看,可能要过几天。 :)
zgb 2005-09-12
  • 打赏
  • 举报
回复
Delphi如何得到标准的参数表?
我想用delphi加密,c#解密。
wuyi8808 2005-09-12
  • 打赏
  • 举报
回复
可能是两种加密方法使用的参数表不一样, 导致加密结果不相同.
zgb 2005-09-12
  • 打赏
  • 举报
回复
两种方法加密的结果为何不同?
.NET有这样的类,是否Delphi的代码不标准?
yizhixiaozhu 2005-07-27
  • 打赏
  • 举报
回复
mark
okyzx 2005-07-27
  • 打赏
  • 举报
回复
呵呵,来迟喽!!楼主可以结贴了吧
wskyo 2005-07-27
  • 打赏
  • 举报
回复
.NET有这样的类
加载更多回复(5)

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧