请creation-zy再帮我一个忙。也请其他大侠来看看,关于DES加密,及硬盘序号加密后如何只产生8位阿拉伯数字的问题。(100分)

  • 主题发起人 主题发起人 dadabox
  • 开始时间 开始时间
D

dadabox

Unregistered / Unconfirmed
GUEST, unregistred user!
我想输出不只是0-9,A-F的密码,我希望是0-9,A-Z,a-z等。请问要怎样做?
另外,我取得硬盘ID后,有可能是8位,10位,12位,甚至更多位。我想统一取成8位的阿拉
伯数值,如何做? 有没有好的算法,产生的值不能随机,只能根据某种算法,而且不同的
ID产生相同的8位序号的机率要尽量最小。硬盘序号有可能是数值,也有可能是字母,所以
不能直接用什么加减乘除,可能要通过某种运算好些。哪位大侠能解决这个问题?
相关链接请看这儿。
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1018638
 
不好意思,我昨天比较忙。

>>0-9,A-Z,a-z
这样取值范围就是10+26*2=62种。不到2^6,好像不太好办。要么增加两个字符,要么砍掉30
个字符。

也许还有别的方法,等我试试看...
 
谢谢!我选增加两个字符。
 
function BytesToText64(PC:PChar;Len:Integer):String;
const
MapArray:array[0..63] of char=('0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S',
'T','U','V','W','X','Y','Z','+','-'); //增加 '+','-'
var
i,n:Integer;
b,b1:Byte;
p,pDest:PChar;
begin
n:=Len*4 div 3;
if Len mod 3>0 then
Inc(n);
SetLength(Result,n);
p:=PC;
pDest:=@Result[1];
for i:=1 to Len div 3 do
begin
b:=Byte(p^);
pDest^:=MapArray[b shr 2];
Inc(pDest);
Inc(p);
b1:=Byte(p^);
pDest^:=MapArray[((b and $03) shl 4) or (b1 shr 4)];
Inc(pDest);
Inc(p);
b:=Byte(p^);
pDest^:=MapArray[((b1 and $0F) shl 2) or (b shr 6)];
Inc(pDest);
pDest^:=MapArray[b and $3F];
Inc(pDest);
Inc(p);
end;
n:=Len mod 3;
if n=0 then
exit;
b:=Byte(p^);
pDest^:=MapArray[b shr 2];
Inc(pDest);
if n=1 then
begin
pDest^:=MapArray[(b and $03) shl 4];
exit;
end;
Inc(p);
b1:=Byte(p^);
pDest^:=MapArray[((b and $03) shl 4) or (b1 shr 4)];
Inc(pDest);
pDest^:=MapArray[(b1 and $0F) shl 2];
end;

function Text64ToBytes(PC:PChar;Len:Integer):String;
function Char64ToByte(Ch:Char):Byte;
begin
case Ch of
'0'..'9':
Result:=Byte(Ch)-Byte('0');
'a'..'z':
Result:=Byte(Ch)-Byte('a')+10;
'A'..'Z':
Result:=Byte(Ch)-Byte('A')+36;
'+':
Result:=62;
else
Result:=63;
end;
end;
var
i,n:Integer;
b,b1:Byte;
p,pDest:PChar;
begin
n:=((Len-1) div 4)*3+(Len-1) mod 4;
SetLength(Result,n);
p:=PC;
pDest:=@Result[1];
for i:=1 to Len div 4 do
begin
b:=Char64ToByte(p^);
Inc(p);
b1:=Char64ToByte(p^);
pDest^:=Char((b shl 2) or (b1 shr 4));
Inc(p);
b:=Char64ToByte(p^);
Inc(pDest);
pDest^:=Char((b1 shl 4) or (b shr 2));
Inc(p);
b1:=Char64ToByte(p^);
Inc(pDest);
pDest^:=Char((b shl 6) or b1);
Inc(p);
Inc(pDest);
end;
n:=Len mod 4;
if n=0 then
exit;
b:=Char64ToByte(p^);
Inc(p);
b1:=Char64ToByte(p^);
pDest^:=Char((b shl 2) or (b1 shr 4));
if n=3 then
begin
Inc(p);
b:=Char64ToByte(p^);
Inc(pDest);
pDest^:=Char((b1 shl 4) or (b shr 2));
end;
end;
//eg:
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text:=BytesToText64(@Edit1.Text[1],Length(Edit1.Text));
end;
procedure TForm1.Edit2Change(Sender: TObject);
begin
Edit3.Text:=Text64ToBytes(@Edit2.Text[1],Length(Edit2.Text));
end;


正在处理序列号...
 
function HashIt(str:string):DWord;
var
i,len,m:byte;
mm:DWord;
begin
len:=Length(str);
mm:=0;
for i:=1 to len do
begin
m:=byte(str);
mm:=mm xor m;
mm:=mm+(Word(m) shl 6);
m:=mm shr 24;
mm:=(mm shl 8) xor m;
end;
Result:=mm xor $58A30716;
end;

eg: Edit4.Text:=IntToStr(HashIt(Edit1.Text) mod 100000000); //Edit1.Text是字符串形式的ID
 
creation-zy,谢谢你!产生8位阿拉伯数字的函数没有问题了。但BytesToText64(PC:PChar;Len:Integer):String;
还有一点疑问,怎么给他8位长的字符,产生出来的是11位,要给他12位长的字符,他才产
生16位的密鈅。我怎样才能无论几个字串都使他产生16位的密钥?
另外,能不能帮忙解释一下?我还是想知道其中原理。如果你解释了我还看不懂,就怪我自
己苯啦。:(
对于你的帮助,我只有用分数来答谢了。这儿有两个问题,没人能解决,你去回个贴,我把
分给你吧。
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1010179
http://www.delphibbs.com/delphibbs/dispq.asp?lid=797710
 
哦,creation-zy,我又犯了一个错误。如果叫用户要用分辨大小写是很烦的一件事情。恐怕
得改成0-9和大写字母,即32位,可我不知道你程序中的原理是怎么来的,改不了。能不能
麻烦你再改一下?能告诉我其中原理吗?谢谢你啦!
 
思路:
如果不满12位,则用#0,#1,#2...依次填补,直到长度够了为止。
如果超过了12位,就将超过的部分减切到临时字符串中,然后对其进行Hash运算,让运算的结果
和前面的12位进行异或运算,最终得到固定的12位结果。
 
creation-zy,我对HASH一点都不懂。哪儿有这方面的资料下?现在,我只要阿拉伯数字和
大写字母的输出,除了将数组变为32位,还有哪些地方要改呢?
 
给你一个通用的——可以实现8Bit<->1..8Bit的转换。

const
MapArray:array[0..63] of char=('0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S',
'T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z','+','-');
type
TByteMapFunc=function (B:Byte):Char;
TMapByteFunc=function (B:Byte):Byte;
//由于数组大小的关系,下面的Map6Bit和Char64ToByte仅能对付1..6bit的数据。
function Map6Bit(B:Byte):Char;
begin
Result:=MapArray;
end;
function Char64ToByte(Ch:Char):Byte;
begin
case Ch of
'0'..'9':
Result:=Byte(Ch)-Byte('0');
'A'..'Z':
Result:=Byte(Ch)-Byte('A')+10;
'a'..'z':
Result:=Byte(Ch)-Byte('a')+36;
'+':
Result:=62;
else
Result:=63;
end;
end;

function HashIt(str:string):DWord;
var
i,len,m:byte;
mm:DWord;
begin
len:=Length(str);
mm:=0;
for i:=1 to len do
begin
m:=byte(str);
mm:=mm xor m;
mm:=mm+(Word(m) shl 6);
m:=mm shr 24;
mm:=(mm shl 8) xor m;
end;
Result:=mm xor $58A30716;
end;

function Bytes8ToBytesN(PC:PChar;Len,Nbit:Integer;ByteMap:TByteMapFunc):String;
var
i,j,m,n:Integer;
Bits:TBits;
begin
if (Nbit<1) or (Nbit>8) then
begin
Result:='';
exit;
end;
n:=Len*8;
i:=n mod Nbit;
if i>0 then
n:=n+Nbit-i;
SetLength(Result,n div Nbit);
Bits:=TBits.Create;
Bits.Size:=n;
//原始Byte信息->Bits[]
m:=0;
for i:=0 to Len-1 do
begin
for j:=7 downto 0 do
begin
Bits[m]:=Boolean((Byte(PC^) shr j) and $01);
Inc(m);
end;
Inc(PC);
end;
while m<n do
begin
Bits[m]:=false;
Inc(m);
end;
//Bits[]->Result[]
m:=0;
for i:=1 to n div Nbit do
begin
Result:=#0;
for j:=0 to Nbit-1 do
begin
Byte(Result):=Byte(Result) shl 1+Byte(Bits[m]);
Inc(m);
end;
if Assigned(ByteMap) then
Result:=ByteMap(Byte(Result));
end;
Bits.Free;
end;

function BytesNToBytes8(PC:PChar;Len,Nbit:Integer;MapByte:TMapByteFunc):String;
var
i,j,m,n:Integer;
Bits:TBits;
B:Byte;
begin
if (Nbit<1) or (Nbit>8) then
begin
Result:='';
exit;
end;
n:=Len*Nbit;
SetLength(Result,n div 8);
Bits:=TBits.Create;
Bits.Size:=n;
//原始Byte信息->Bits[]
m:=0;
for i:=0 to Len-1 do
begin
B:=Byte(PC^);
if Assigned(MapByte) then
B:=MapByte(B);
for j:=Nbit-1 downto 0 do
begin
Bits[m]:=Boolean((B shr j) and $01);
Inc(m);
end;
Inc(PC);
end;
while m<n do
begin
Bits[m]:=false;
Inc(m);
end;
//Bits[]->Result[]
m:=0;
for i:=1 to n div 8 do
begin
Result:=#0;
for j:=0 to 7 do
begin
Byte(Result):=Byte(Result) shl 1+Byte(Bits[m]);
Inc(m);
end;
end;
Bits.Free;
end;

procedure TForm1.Edit3DblClick(Sender: TObject);
var
mstr:String;
begin
mstr:=Bytes8ToBytesN(@Edit3.Text[1],Length(Edit3.Text),5,@Map6Bit);
ShowMessage('Text:'#13+Edit3.Text+#13+'New text:'#13+mstr);
Caption:=BytesNToBytes8(@mstr[1],Length(mstr),5,@Char64ToByte);
end;

>>对HASH一点都不懂
Hash函数的目的就是对任意长度的信息进行处理,生成固定长度的信息。我上面的
function HashIt(str:string):DWord; 就是一个典型的Hash函数。

if Length(Str)>12 then
begin
mstr:=Copy(Str,13,Length(Str)-12);
Delete(Str,13,Length(Str)-12);
PDWord(@Str[1])^:=PDWord(@Str[1])^ xor HashIt(mstr);
end;
//现在Str的长度已经不可能大于12了
 
creation-zy, 不要说我笨哈。我还是看不太懂。怎么这儿生成的序号都是有规律的呢?
比如1产生的是31,无论在第几个位置,这个字串多长,都是产生31。这样就没有多大意义
了。我想的是通过一种算法,给一个字串,根据其长度不同,所在位置不同,都会产生一个
完全不一样的号码出来。而输出的结果希望是固定长的,比如8位,10位,而且,希望能只
是阿拉伯数字,或是我指定的其他字符。我想将你上面的64位数组的改成32位的,但不知怎
么改。能否给我讲讲。谢谢!
上午打了半天,好像大富翁后来不能上了,结果全没有。:(
 
>>这儿生成的序号都是有规律的
老大,我上面的ByteToXXXX等函数都是为加密之后的Buffer服务的,只是普通的编码过程,
没有任何加密的成分,当然是有规律的。你只要让加密过程没有规律可寻就可以了。

>>64位数组的改成32位的
我在上面不是已经写了吗?——Bytes8ToBytesN and BytesNToBytes8,具体的用法也写出来
了: Edit3DblClick
 
creation-zy, 谢谢啦! 前两天没时间,我再试一下,不懂再问你哈。
 
后退
顶部