//这是大数的结构
THfdInt = Record
aByBuffer:Array[0..239] of Byte;
dwLen : LongWord;
End;
THfdIntTable = Record
aBig:array[0..16] of THfdInt;
end;
TCompare = (Lt, St, Eq, Er);
function DoCode( var BigIndexOut,BigSubOut,paBigMagic,
paBigKey:THfdInt):integer;
var
CmpResult:TCompare;
BigSub,BigSearchIndex,BigTmp3:THfdInt;
iIn1Len_1:integer;
iMaxIndex,iIndex,iMinIndex:integer;
IntTable:THfdIntTable;
begin
result := 0;
if paBigKey.dwLen = 0 then
exit;
CmpResult := HfdIntCompare(paBigMagic,paBigKey);
if (CmpResult = LT) or (CmpResult = EQ) then
begin
//paBigMagic <= paBigKey
HfdIntCopy(BigSub,IntTable.aBig[$10]);
HfdIntCopy(BigSearchIndex,IntTable.aBig[$10]);
HfdDoCreateIndexTable(IntTable,paBigKey); //根据key产生索引表
iIn1Len_1 := paBigMagic.dwLen - 1;
if iIn1Len_1 >= 0 then
begin
repeat
if HfdDoShr(IntTable,BigSub,paBigMagic,
paBigKey,iIn1Len_1) <= 0 then
break;
//二分法查找
iMaxIndex := $f;
iMinIndex := 1;
repeat
iIndex := iMaxIndex+iMinIndex;
iIndex := iIndex shr 1;
CmpResult := HfdIntCompare(IntTable.aBig[iIndex],BigSub);
if CmpResult=EQ then
break;
if (CmpResult = LT) then
iMaxIndex := iIndex - 1;
if (CmpResult = ST) then
iMinIndex := iIndex + 1;
until(iMinIndex > iMaxIndex) ;
//查找完成
if not(CmpResult = EQ) then
iIndex := (iMinIndex - 1) and $ff;
BigSearchIndex.aByBuffer[iIn1Len_1+1] := byte(iIndex);
if CmpResult = EQ then
begin
HfdIntCopy(BigSub,IntTable.aBig[$F]);
end
else//if CmpResult = EQ then
begin
// 大数减 BigSub = BigSub - IntTable.aBig[iIndex]
HfdIntSub(BigSub,IntTable.aBig[iIndex],BigTmp3);
HfdIntCopy(BigSub,BigTmp3);
end; //if CmpResult = EQ then else
until(iIn1Len_1 < 0) ;
end;//if iIn1Len_1 >= 0 then
FGint.HfdIntSetLen(BigSearchIndex,paBigMagic.dwLen-paBigKey.dwLen);
HfdIntCopy(BigSubOut,BigSub);
HfdIntCopy(BigIndexOut,BigSearchIndex);
result := 1;
end ////if iIn1Len_1 >= 0 then else
else//if (CmpResult = LT) or (CmpResult = ET) then
begin
//初始化 如果 paBigMagic > paBigKey
HfdIntCopy(BigIndexOut,IntTable.aBig[$10]);
HfdIntCopy(BigSubOut,paBigMagic);
result := 1;
end;//if (CmpResult = LT) or (CmpResult = ET) then else
end;
function HfdDoCreateIndexTable(var IntTable:THfdIntTable;
const BigIntSeed:THfdInt):integer;
// 这个函数产生索引表,结构很简单
//[0] = 0;
//[1] = BigIntSeed
//[2] = [1] + BigIntSeed
//[3] = [2] + BigIntSeed
......
var
i:integer;
begin
HfdIntSetZore(IntTable.aBig[0]);
HfdIntCopy(IntTable.aBig[1],BigIntSeed);
for I := 2 to 15 do
begin
HfdIntAdd(BigIntSeed,IntTable.aBig[i-1],IntTable.aBig[i]);
end;
result := 1;
end;
function HfdDoShr(var IntTable:THfdIntTable;
var BigOut,BigInt3,BigInt4:THfdInt;
var iNum:integer):integer;
var
iLenDiff:integer;
CmpResult : TCompare;
begin
repeat
iLenDiff := BigInt4.dwLen - BigOut.dwLen;
if iLenDiff>0 then
begin
if iNum>=(iLenDiff-1) then
begin
iNum := iNum - iLenDiff;
HfdIntShr(IntTable,BigOut,BigOut,iLenDiff);//低位向高位移iLenDiff 字节 (右移)
if iLenDiff <> 0 then
begin
CopyMemory(addr(BigOut.aByBuffer[0]),
addr(BigInt3.aByBuffer[iNum+1]),iLenDiff );
end;
HfdIntSetLen(BigOut); //调整长度
end
else //if iN>=(iLenDiff-1) then
begin //lb1
HfdIntShr(IntTable,BigOut,BigOut,iNum+1);
if iNum+1 > 0 then
CopyMemory(addr(BigOut.aByBuffer[0]),
addr(BigInt3.aByBuffer[0]),iNum+1 );
HfdIntSetLen(BigOut); //调整长度
result := 0 ;
exit;
end;//if iN>=(iLenDiff-1) then
end; //if iLenDiff>0 then
//lbcmp
CmpResult := HfdIntCompare(BigOut,BigInt4);
if (CmpResult = ST) or (CmpResult = ER) then
begin
if (iNum < 0) then
begin
result := 0 ;
exit;
end;
HfdIntShr(IntTable,BigOut,BigOut,1);
BigOut.aByBuffer[0] := BigInt3.aByBuffer[iNum];
dec(iNum);
if BigOut.dwLen = 0 then
begin
if BigOut.aByBuffer[0]<>0 then
BigOut.dwLen := 1;
end;
end;//if (CmpResult = ST) or (CmpResult = ER) then
until (BigOut.dwLen >= BigInt4.dwLen) ;
result := 1;
end;//function HfdDoSomeCopy1(var IntTable:THfdIntTable;
// var BigOut,BigInt3,BigInt4:THfdInt;
// iNum:integer):intger;
function HfdIntCompare(Const HfdInt1, HfdInt2 : THfdInt) : TCompare;
Var
size1, size2, i : integer;
Begin
result := Er;
size1 := HfdInt1.dwLen;
size2 := HfdInt2.dwLen;
If size1 > size2 Then result := Lt Else
If size1 < size2 Then result := St Else
Begin
i := size2-1;
While (HfdInt1.aByBuffer[i] = HfdInt2.aByBuffer[i])
And (i > 0) Do
i := i - 1;
If HfdInt1.aByBuffer[i] = HfdInt2.aByBuffer[i] Then
result := Eq
Else
If HfdInt1.aByBuffer[i] < HfdInt2.aByBuffer[i] Then
result := St
Else
If HfdInt1.aByBuffer[i] > HfdInt2.aByBuffer[i] Then
result := Lt;
End;