Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   calculo de CRC Xmodem (https://www.clubdelphi.com/foros/showthread.php?t=60663)

emeceuy 09-10-2008 14:07:20

calculo de CRC Xmodem
 
Estimados, hola !

Les comento el GRAN :o problema que tengo ! Estoy trabajando con una aplicación que envia datos a un dispositivo a través de un puerto serial. El problema es que cada cadena de datos que se le envía tiene al final 2 bytes de CRC.

Para un dispositivo que usa CRC-16 confeccioné un procedimiento (que no será eficiente, pero funciona) y calcula muy bien el CRC ! El problema es que al comunicarme con otro tipo de dispositivo que usa CRC-16 XMODEM no funciona ! y creo que la unica diferencia que hay es el polinomio generador.

Como me di cuenta que CRC utiliza cada dispositivo? en esta página: http://www.lammertbies.nl/comm/info/...+A5&method=hex

Entonces, que puede ser? Tres posibilidades:

1. Agrego abajo el codigo que utilizo por si alguien lo quiere analizar y capaz que ven algun error.
2. Alguien conoce algun lugar de donde descargar una funcion que se le pueda pasar un string de datos y devuelva su CRC 16 XMODEM?
3. He visto varias funciones en internet, pero están en "C", hay manera de utilizarlas en delphi? (como se puede hacer con Assembler, por ejemplo)?

Muchisimas gracias desde ya ! salu2 !

Código Delphi [-]
procedure fCalculaCRC; 
  
  // FUNCIONES AUXILIARES

  function ComparaXOR(Datos1,Datos2: string):string; 
  var vloop:integer; 
      vbol1,vbol2:boolean; 
  begin 
    if length(Datos1)<>length(Datos2) then showmessage('Error'); 
    for vloop:=1 to length(Datos2) do 
      begin 
        if Datos1[vloop]='1' then vbol1:=true else vbol1:=false; 
        if Datos2[vloop]='1' then vbol2:=true else vbol2:=false; 
        if vbol1 xor vbol2 then result[vloop]:='1' else result[vloop]:='0'; 
      end; 
    result:=trim(result); 
  end; 

  function EliminaMSB(Datos:string):string; 
  begin 
    EliminaMSB:=trim(copy(Datos,2,999)); 
  end; 

  function ProximoDato:string; 
    begin 
      if length(vBinario)>0 then ProximoDato:=vBinario[1] 
       else 
         begin 
           ProximoDato:='0'; 
           showmessage('Error'); 
         end; 
       vBinario:=trim(copy(vBinario,2,999)); 
    end; 

  function Invierte(Datos: string):string; 
  var vloop:integer; 
  begin 
    for vloop:=1 to length(Datos) do result[vloop]:=Datos[length(Datos)+1-vloop]; 
    result:=trim(result); 
  end; 

  // AQUI COMIENZA LA FUNCION PROPIAMENTE DICHA

   begin 
      vBinario:=''; 
      for vloop:=0 to length(pDatos)-1 do vBinario:=vBinario+Invierte(inttobin(pDatos[vloop])); 

      vGenerador:='10001000000100001'; 
      vCeros:='00000000000000000'; 

      vBinario:=vBinario+copy(vCeros,1,length(vCeros)-1);        // 16 bits por el CRC-16 

      vLargoDAT:=length(vBinario); 
      vLargoGEN:=length(vGenerador); 
      setlength(mCRC,0,0); 
      setlength(mCRC,vLargoDAT-vLargoGEN+10,17); 

      vResultado:='X'+copy(vBinario,1,vLargoGEN-1); 
      vBinario:=trim(copy(vBinario,vLargoGEN,999)); 

      repeat 
         begin 
            vDividendo:=EliminaMSB(vResultado)+ProximoDato; 
            if vDividendo[1]='1' then vDivisor:=vGenerador else vDivisor:=vCeros; 

            vResultado:=DATparaXOR(vDividendo,vDivisor); 

            if vResultado[1]='1' then showmessage('Error, MSB del resultado es "1"'); 
         end 
      until length(vBinario)=0; 

      vResultado:=Invierte(EliminaMSB(vResultado)); 

      vCRCH:=bintoint(copy(vresultado,9,8)); 
      vCRCL:=bintoint(copy(vresultado,1,8)); 

      vCaracteres:=vCaracteres+char(vCRCH)+char(vCRCL); 
end;


La franja horaria es GMT +2. Ahora son las 13:45:25.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi