Usamos essa função:
iCalculo := ChkSum( G_Usuario->Matricula + G_Usuario->Nome )
IF G_Usuario->ChkSum == iCalculo
? "Ok"
ELSE
? "Erro"
ENDIF
Gravando o ChkSum
GA_Usuario->ChkSum := ChkSum( GA_Usuario->Matricula + G_Usuario->Nome )
****
* Gera a string de validação de um registro
*
FUNCTION ChkSum( cRegistro )
LOCAL nCount, nChkSum, cRegAux, nChkAnt
cRegAux:=""
FOR nCount:=1 TO Len( cRegistro )
IF SubStr( cRegistro, nCount, 1 ) <> " "
cRegAux += SubStr( cRegistro, nCount, 1 )
ENDIF
NEXT
nChkSum := 0
FOR nCount:=1 TO Len(cRegAux)
nChkSum += Int( ( Asc( SubStr( cRegAux, nCount, 1 ) ) * ( Len( cRegAux ) * nCount ) ) *33 )
NEXT
nChkAnt := nChkSum
nChkSum := VAL( SubStr( AllTrim( Str( nChkSum ) ), ( Len( AllTrim( Str( nChkSum ) ) ) -2 ), 2 ) + ;
SubStr( AllTrim( Str( nChkSum ) ), 1,( Len( AllTrim( Str( nChkSum ) ) ) -2 ) ) )
*** compatibilidade com try ... except do Delphi ***
IF nChkSum > 2147483647 // maior tamanho de inteiro do Delphi
nChkSum := nChkAnt
nChkSum := ;
Val( SubStr( ( SubStr( AllTrim( Str( nChkSum ) ), ( Len( AllTrim( Str( nChkSum ) ) ) -2 ), 2 ) +;
SubStr( AllTrim( Str( nChkSum ) ), 1, ( Len( AllTrim( Str( nChkSum ) ) ) -2 ) ) ), 1, 9 ) )
ENDIF
WHILE nChkSum > 65535
nChkSum := Int( nChkSum / 2 )
END
RETURN IntToHex( nChkSum, 4 )
****
* Converte inteiro para hexadecimal
*
FUNCTION IntToHex( nDec, nCasas )
LOCAL cSign, cHex:="", aRestos:={}, nPos, nDig
IF nDec < 0
nDec := nDec * -1
cSign := "-"
ELSE
cSign := ""
ENDIF
WHILE nDec > 15
aAdd( aRestos, nDec % 16 )
nDec := Int( nDec / 16 )
END
aAdd( aRestos, nDec )
FOR nPos := Len( aRestos ) TO 1 STEP -1
nDig := aRestos[nPos]
cHex += Chr( nDig + IF( nDig < 10, 48, 55 ) )
NEXT
RETURN cSign + PADL( cHex, nCasas, "0" )