CRC64
Добавлено: 25.01.2015 (Вс) 19:26
Здравы будьте, форумчане!
На просторах интернета набрёл на Параллельное вычисление CRC64
Из приложенных к статье исходников на Delphi пытаюсь частично перевести на PowerBasic
Интересует процедура ShaNormalRefreshCRC64, как самая быстрая из представленных...
Объявление примет вид Function ShaNormalRefreshCRC64(ByVal BufPtr As Byte Ptr, BufLen As Dword) As Quad.
А вот с телом функции, даже и не знаю, нужно что-то делать или нет?..
Ещё есть инициализация таблиц:
И вспомогательная функция:
Примет вид:
Всё, что касается заполнения таблиц перевёл так:
После испраления всех ошибок встанет вопрос проверки выдаваемых CRC64 этим алгоритмом с CRC64 некой проверенной софтины...
На просторах интернета набрёл на Параллельное вычисление CRC64
Из приложенных к статье исходников на Delphi пытаюсь частично перевести на PowerBasic
Интересует процедура ShaNormalRefreshCRC64, как самая быстрая из представленных...
- Код: Выделить всё
procedure ShaNormalRefreshCRC64(var CRC: int64; BufPtr: pointer; BufLen: integer);
asm
test edx, edx
jz @ret
neg ecx
jz @ret
push ebx
push esi
push eax
mov ebx, [eax+4]
mov esi, [eax]
bswap ebx
bswap esi
xor eax, eax
@head:
test dl, 3
jz @bodyinit
mov al, byte [edx]
inc edx
xor al, bl
shrd ebx, esi, 8
xor ebx, [eax*8 + ByteSwappedTable64]
shr esi, 8
xor esi, [eax*8 + ByteSwappedTable64 + 4]
add ecx, 1
jnz @head
bswap ebx
bswap esi
pop eax
mov [eax+4], ebx
mov [eax], esi
pop esi
pop ebx
@ret:
ret
@bodyinit:
sub edx, ecx
add ecx, 8
jg @bodydone
push edi
push ebp
mov ebp, ecx
// crc64: ebx-lo esi-hi
// data: eax-lo ecx-hi
// buffer: edx-base ebp-count
// table: edi-index
@bodyloop:
mov eax, [edx + ebp - 8]
xor eax, ebx
movzx edi, al
mov ecx, [edx + ebp - 4]
xor ecx, esi
mov ebx, [edi*8 + ByteSwappedTable64 + 2048*7]
mov esi, [edi*8 + ByteSwappedTable64 + 2048*7 + 4]
movzx edi, ah
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*6]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*6 + 4]
shr eax, 16
movzx edi, al
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*5]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*5 + 4]
movzx edi, ah
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*4]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*4 + 4]
movzx edi, cl
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*3]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*3 + 4]
movzx edi, ch
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*2]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*2 + 4]
shr ecx, 16
movzx edi, cl
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*1]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*1 + 4]
movzx edi, ch
xor ebx, [edi*8 + ByteSwappedTable64 + 2048*0]
xor esi, [edi*8 + ByteSwappedTable64 + 2048*0 + 4]
add ebp, 8
jle @bodyloop
mov ecx, ebp
pop ebp
pop edi
@bodydone:
sub ecx, 8
je @result
xor eax, eax
@tail:
mov al, byte [edx + ecx]
xor al, bl
shrd ebx, esi, 8
xor ebx, [eax*8 + ByteSwappedTable64]
shr esi, 8
xor esi, [eax*8 + ByteSwappedTable64 + 4]
add ecx, 1
jnz @tail
@result:
bswap ebx
bswap esi
pop eax;
mov [eax+4], ebx
mov [eax], esi
pop esi
pop ebx
end;
Объявление примет вид Function ShaNormalRefreshCRC64(ByVal BufPtr As Byte Ptr, BufLen As Dword) As Quad.
А вот с телом функции, даже и не знаю, нужно что-то делать или нет?..
Ещё есть инициализация таблиц:
- Код: Выделить всё
function CRC64Init: boolean;
const
EcmaPoly= $42F0E1EBA9EA3693; //ECMA DLT standard (normal form), reflected form = $C96C5795D7870F42;
//Other found polinomials
OldProteinReflectedPoly= $d800000000000000; //Bad poly (reflected ISO 3309) - too many collisions on proteins with two mutations
NewProteinReflectedPoly= $95AC9329AC4BC9B5; //By David T. Jones for protein data banks(reflected form)
var
Poly, ReflectedPoly, c: int64;
i, j: integer;
begin;
Poly:=EcmaPoly;
ReflectedPoly:=$C96C5795D7870F42;
//ReflectedPoly:=NewProteinReflectedPoly;
for i:=0 to 255 do begin;
c:=i;
for j:=1 to 8 do if odd(c)
then c:=(c shr 1) xor ReflectedPoly
else c:=(c shr 1);
ReflectedTable64[0][i]:=c;
c:=i;
c:=c shl 56;
for j:=1 to 8 do if c<0
then c:=(c shl 1) xor Poly
else c:=(c shl 1);
ReferenceTable64[i]:=c;
ByteSwap(c);
ByteSwappedTable64[0][i]:=c;
end;
for i:=0 to 255 do begin;
c:=ReflectedTable64[0][i];
for j:=1 to 7 do begin;
c:=(c shr 8) xor ReflectedTable64[0][byte(c)];
ReflectedTable64[j][i]:=c;
end;
c:=ByteSwappedTable64[0][i];
for j:=1 to 7 do begin;
c:=(c shr 8) xor ByteSwappedTable64[0][byte(c)];
ByteSwappedTable64[j][i]:=c;
end;
end;
Result:=true;
' необходимость дальнейших строк сомнительна
c:=-1; ReferenceRefreshCRC64(c,@ReferenceTable64[0],SizeOf(ReferenceTable64));
Result:=Result and ($305CD291B39AA09A=not c);
c:=-1; NormalRefreshCRC64(c,@ByteSwappedTable64[0,0],SizeOf(ByteSwappedTable64));
Result:=Result and ($F0347B5C2C7411D2=not c);
c:=-1; ShaNormalRefreshCRC64(c,@ByteSwappedTable64[0,0],SizeOf(ByteSwappedTable64));
Result:=Result and ($F0347B5C2C7411D2=not c);
if ReflectedPoly=$C96C5795D7870F42 then begin;
c:=-1; ReflectedRefreshCRC64(c,@ReflectedTable64[0,0],SizeOf(ReflectedTable64));
Result:=Result and ($014ED9B63590C55E=not c);
c:=-1; ShaReflectedRefreshCRC64(c,@ReflectedTable64[0,0],SizeOf(ReflectedTable64));
Result:=Result and ($014ED9B63590C55E=not c);
end;
end;
И вспомогательная функция:
- Код: Выделить всё
procedure ByteSwap(var Value: int64);
asm
mov ecx, [eax]
mov edx, [eax+4]
bswap ecx
bswap edx
mov [eax+4], ecx
mov [eax], edx
end;
Примет вид:
- Код: Выделить всё
Function SwapQuad(ByVal QuadVar As Quad) As Quad
Prefix "ASM"
mov ecx, [eax]
mov edx, [eax+4]
bswap ecx
bswap edx
mov [eax+4], ecx
mov [eax], edx
End Prefix
End Function
Всё, что касается заполнения таблиц перевёл так:
- Код: Выделить всё
%EcmaPoly = &H42F0E1EBA9EA3693&&
%ReflectedPoly = &HC96C5795D7870F42&&
Global ByteSwappedTable64() As Quad ' array[0..7] of array[0..255] of int64
Global ReflectedTable64() As Quad
Sub InitCRC_64
Local v As Quad
Register I As Dword, J As Dword
ReDim ByteSwappedTable64(7, 255)
ReDim ReflectedTable64(7, 255)
For I = 0 To 255
v = I
For J = 1 To 8
If v And 1 Then
Shift Right V, 1
v = v Xor %ReflectedPoly
Else
Shift Right v, 1
End If
Next J
ReflectedTable64(0, I) = v
v = I
Shift Left v, 56
For J = 1 To 8
If v < 0 Then
Shift Left v, 1
v = v Xor %EcmaPoly
Else
Shift Left v, 1
End If
Next J
ByteSwappedTable64(0, I) = SwapQuad(ByVal v)
Next I
For I = 0 To 255
v = ReflectedTable64(0, I)
For J = 1 To 7
Shift Right v, 8
ReflectedTable64(J, I) = v Xor ReflectedTable64(0, CByt(v))
Next J
v = ByteSwappedTable64(0, I)
For J = 1 To 7
Shift Right v, 8
ByteSwappedTable64(J, I) = v Xor ByteSwappedTable64(0, CByt(v))
Next J
Next I
End Sub
После испраления всех ошибок встанет вопрос проверки выдаваемых CRC64 этим алгоритмом с CRC64 некой проверенной софтины...