Форум: "Основная";
Текущий архив: 2002.02.04;
Скачать: [xml.tar.bz2];
ВнизНужна приличная и Найти похожие ветки
← →
Digitman (2002-01-18 12:09) [1]а надо ? именно хэш ? до сих пор я успешно обходился обычной CRC32, и проблем не было. Главное здесь - включить в уник.индекс несколько CRC, вычисленных по тем полям, комбинация значений которых д.б. уникальна. Тогда и вероятность дублирования уник.индекса будет астрономически ничтожной.
Вот, посмотри, чем я пользуюсь, к примеру, в IB UDF, когда необходимо вычислить контр.сумму BLOB-поля :
const
//CRC32-полином для расчета таблицы
CRC32Poly = $EDB88320; //WinZip использует именно такое зн-е полинома, но можно и изменить на свое, чуть подумав
type
TCRC32 = Longword;
PCRC32 = ^TCRC32;
TCRC32Table = array[0..255] of TCRC32;
PCRC32Table = ^TCRC32Table;
var
CRC32Table: PCRC32Table;
procedure MakeCRC32Table(
CRC32Table: PCRC32Table; // указатель на CRC32-таблицу, которую требуется заполнить
const InitCRC: TCRC32 // исходный CRC32-полином для расчета таблицы
);
var
i,j: Integer;
r: TCRC32;
begin
for i:= Low(TCRC32Table) to High(TCRC32Table) do begin
r:= i;
for j:= 8 downto 1 do
if (r and 1) = 1 then
r:= (r shr 1) xor InitCRC
else
r:= r shr 1;
CRC32Table[i]:= r;
end;
end;
function GetCRC32(
const Buffer; // ссылка на буфер, CRC32 которого д.б.расчитана
BufSize: DWord; // размер буфера
InitCRC: TCRC32; // вх.значение CRC32, обычно - $FFFFFFFF (-1)
const Inv: Boolean // инвертировать ли результат (обычно - True)
): TCRC32;
var
BufPtr: PByte;
begin
BufPtr:= PByte(Buffer);
while BufSize > 0 do begin
InitCRC:= CRC32Table[LoByte(InitCRC) xor BufPtr^] xor (InitCRC shr 8);
Inc(BufPtr);
Dec(BufSize);
end;
Result:= InitCRC;
if Inv then
Result:= not Result;
end;
...
//расчет контр.суммы BLOB-поля
function GetBlobCheckSum(Blob: PBlob): PCRC32;
var
CRC32: TCRC32;
SegBuf: Pointer;
BytesRemains, BytesRead: Integer;
begin
Result:= nil;
if Assigned(Blob) then with Blob^ do
if Assigned(BlobHandle) and Assigned(GetSegment) then
try
GetMem(SegBuf, MaxSegmentLength);
BytesRead:= 0;
CRC32:= CRC32InitMask;
try
BytesRemains:= TotalSize;
while (BytesRemains > 0) and Boolean(GetSegment(BlobHandle, SegBuf, Min(BytesRemains, MaxSegmentLength), BytesRead)) do begin
CRC32:= GetCRC32(SegBuf^, BytesRead, CRC32, False);
Dec(BytesRemains, BytesRead);
BytesRead:= 0;
end;
finally
FreeMem(SegBuf);
end;
Result:= PCRC32(Blob);
Result^:= not CRC32;
except
//исключение гасится, в IB возвращается Null, сигн.об исключении в UDF
Result:= nil;
end
end;
initialization
New(CRC32Table); // выделить память под CRC32-таблицу
MakeCRC32Table(CRC32Table, CRC32Poly); // заполнить таблицу
finalization
Dispose(CRC32Table); // освободить память под таблицу
...
это - скрипт для объявления UDF в IB :
DECLARE EXTERNAL FUNCTION GETBLOBCHECKSUM
BLOB
RETURNS INTEGER
ENTRY_POINT "GetBlobCheckSum" MODULE_NAME "my_udf.dll";
это - фрагмент скрипта триггера, в котором требуется получить CRC нового/обновленного BLOB-поля :
...
new.MyBlob_CRC_Field = GetBlobCheckSum(new.MyBlobField);
/* можно и не делать след.проверку, если
MyBlob_CRC_Field объявлено как "not Null" */
if (new.MyBlob_CRC_Field is Null) then
exception E_SOME_PREDEFINED_EXCEPTION_ON_THIS_SITUATION;
...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.02.04;
Скачать: [xml.tar.bz2];
Память: 0.45 MB
Время: 0.004 c