Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-02-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.119
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Convertir código C++ a Delphi (para lograr un cierto "CRC" de una cadena de entrada)

Hola a todos,

Me han encargado cierta tarea para la que no parezco estar capacitado... creo que el código C++ que me han pasado debería ser más completo, en todo caso, pero, como no controlo C++... tampoco sé hasta qué punto algunas partes del código pueden deducirse, por decirlo así...

El código en cuestión es el siguiente:

Código:
while (--count >= 0)
{
  ushort z = (ushort)(data[x++] << 8);

  crc = (ushort)(crc ^ z);

  i = 8;

  do
  {
    if ((crc & 0x8000) != 0)
      crc = (ushort)(crc << 1 ^ 0x1021);
    else
      crc = (ushort)(crc << 1);

  } while (--i > 0);
}
Se supone que "data" es una cadena tal que la siguiente, mejor dicho, una cadena exactamente como la siguiente:

Cita:
13|0000123|1|Maximilian|Mustermann|05051999|21092019
Dicho "data" debería producir un "CRC" exactamente igual a: 5320

Hay cosas que se me escapan, como la variable "x", que, entiendo que es la posición / caracter, de la variable "data". De este modo, he conseguido armar el siguiente código... que ya me sorprende que compile... y se ejecute sin errores aparentes...

Código Delphi [-]
var
  S: string;
  I, X: Integer;
  Z: UInt;
  CRC: Word;
  SLength, N: Integer;
begin
  S := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';

  SLength := Length(S);

  X := 0;
  CRC := 0;

  while SLength >= 0 do
  begin
    Z := Word(S[X]) shl 8;

    CRC := CRC xor Z;

    for I := 8 downto 0 do
    begin

     if (CRC and $08000) <> 0 then
       CRC := (CRC shl 1) xor $1021
     else
       CRC := (CRC shl 1);

    end;

    Inc(X);
    Dec(SLength);
  end;

  // Resultado: 30841, o sea, no el esperado: 5320
  ShowMessage(IntToStr(CRC));
end;

Sin embargo, el resultado que obtengo en "CRC", es 30841, o sea, no 5320. Por otro lado, si no inicializo la variable CRC, es decir, el siguiente código:

Código Delphi [-]
var
  S: string;
  I, X: Integer;
  Z: UInt;
  CRC: Word;
  SLength, N: Integer;
begin
  S := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';

  SLength := Length(S);

  X := 0;

  while SLength >= 0 do
  begin
    Z := Word(S[X]) shl 8;

    CRC := CRC xor Z;

    for I := 8 downto 0 do
    begin

     if (CRC and $08000) <> 0 then
       CRC := (CRC shl 1) xor $1021
     else
       CRC := (CRC shl 1);

    end;

    Inc(X);
    Dec(SLength);
  end;

  // Resultado: 62152, o sea, no el esperado: 5320
  ShowMessage(IntToStr(CRC));
end;

... sigo sin obtener el resultado esperado... en fin... reconozco que estoy perdido: porque no sé si estoy traduciendo el código C++ en condiciones (diría que no), porque, o sé siquiera cómo es que se puede ejecutar el código Delphi mostrado sin errores... y, finalmente, porque no sé si es que el código que me han dado para traducir... en realidad no puede traducirse, puesto que falten datos...

¿Alguna posible ayuda?

¡Muchísimas gracias de antemano!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #2  
Antiguo 18-02-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.202
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
El código en C tiene cosas que faltan.

1. crc debe estar inicializado.
2. Si asumimos la cadena como "estilo C", x debe inicializarse a 0.
3. Asumimos que count el la longitud de la cadena pero debería estar en el código y su cálculo correspondiente.
4. Tampoco sabemos si la cadena es unicode.


Con el código C preparado de esta forma, el resultado es 17940:
Código PHP:
typedef WORD ushort;

int GetCRC()
{
  
CHAR *data "13|0000123|1|Maximilian|Mustermann|05051999|21092019";
  
ushort crc 0;
  
int x 0;
  
int i;
  
int count lstrlen(data);
  while (--
count >= 0){
    
ushort z = (ushort)(data[x++] << 8);
    
crc = (ushort)(crc z);
    
8;
    do{
      if ((
crc 0x8000) != 0)
        
crc = (ushort)(crc << 0x1021);
      else
        
crc = (ushort)(crc << 1);
    } while (--
0);
  }
  return 
crc;


La traducción equivalente a delphi usando String, devuelve el mismo resultado (17940):
Código Delphi [-]
function GetCRC: integer;
var
  S: String;
  i, x: Integer;
  z: WORD;
  CRC: WORD;
  SLength, n: Integer;
begin
  S := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  CRC:= 0;
  SLength := Length(S);
  X := 1;
  while SLength > 0 do
  begin
    Z := WORD(S[X]) shl 8;
    CRC := CRC xor Z;
    i:= 8;
    repeat
      if (CRC and $08000) <> 0 then
        CRC := (CRC shl 1) xor $1021
      else
        CRC := (CRC shl 1);
      dec(i);
    until i <= 0;
    Inc(X);
    Dec(SLength);
  end;
  Result:= CRC;
end;


Alcaraciones sobre la traducción:
1. Las cadenas delphi empiezan el indice = 1; en C comienzan en 0
2. x++ significa que tras las evaluaciones/operaciones se incrementará x
3. --i significa que i de decrementa antes que cualquier otra cosa que de haga con i (por ello uso repeat - until decrementando i consiguiendo una traducción casi literal) y por lo mismo cambio el límite de count en su bucle.


Conclusión: ambos códigos arrojan el mismo resultado y "algo" falta en la inicialización de las variables, probablemente en crc




Saludos.

Última edición por escafandra fecha: 18-02-2020 a las 01:02:13.
Responder Con Cita
  #3  
Antiguo 18-02-2020
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.927
Poder: 26
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por dec Ver Mensaje
debería ser más completo
Definitivamente, no estan ni las variables inicializadas. No tienes eso siquiera?

No te han dicho que algoritmo de crc usan?

Nota:

Y usando https://crccalc.com/ no da con ninguno de los algoritmos comunes.
__________________
El malabarista.

Última edición por mamcx fecha: 18-02-2020 a las 03:58:29.
Responder Con Cita
  #4  
Antiguo 18-02-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.202
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por mamcx Ver Mensaje
Definitivamente, no estan ni las variables inicializadas. No tienes eso siquiera?

No te han dicho que algoritmo de crc usan?

Nota:

Y usando https://crccalc.com/ no da con ninguno de los algoritmos comunes.
Tal como está el código que expuse el algoritmo es CRC-16/XMODEM
Pero faltan datos de inicialización del CRC para que de el resultado esperado.

Saludos.
Responder Con Cita
  #5  
Antiguo 18-02-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.119
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Qué puede uno decir... ya sabía yo (incluso asumía) que iban a tratar de echarme una mano... ¡desde luego si el ClubDelphi no existiera habría que inventarlo! Con todos vosotros en el mismo, claro.

Ya he informado a quien me encargó la tarea que, aparentemente, algo falta en el código... puesto que no es posible obtener la misma salida de la entrada proporcionada a modo de ejemplo.

Ciertamente, se me pasó comentar aquí que ofrecieron algo de documentación:

http://srecord.sourceforge.net/crc16-ccitt.html

... sin embargo, no lo comenté, porque, buscando información sobre este algoritmo en concreto, conseguí cierta ayuda a través de StackOverflow (y el inefable Remy Lebeau), pero, resulta que ocurría lo propio: de la misma entrada, no se obtenía la misma salida... empero, el algoritmo está bien implementado, por lo que se ve, por los ejemplos de entrada y salida que se ofrecen en la propia documentación, que, en este caso sí parecen coincidir.

De modo que pensé que acaso no había que seguir esa documentación al pie de la letra, sino que, en realidad el cálculo del CRC en cuestión no seguía esa documentación (aunque curiosamente la enlazaban...) sino que era sólo el código C++ que nos habían dado a modo de ejemplo. Empero, como se ha visto, este código no produce la salida esperada...

Y yo de mí no me fiaba, de mi traducción a Delphi, quiero decir, pero, de la vuestra me fío, de modo que, algo raro hay aquí...

Os mantendré informado sobre este asunto, a ver en qué queda todo, y, una vez más, ¡muchísimas gracias por vuestra ayuda!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
Antiguo 18-02-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.202
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Por si te sirve de ayuda, inicializando crc = 3077 da el resultado esperado.

Saludos.
Responder Con Cita
  #7  
Antiguo 18-02-2020
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.119
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Cita:
Empezado por escafandra Ver Mensaje
Por si te sirve de ayuda, inicializando crc = 3077 da el resultado esperado.

Saludos.
Joroba, escafandra... claro que sirve, puesto que al menos lo diré... a ver si es que ese es el número "mágico"... voy a comentarlo y en todo caso os mantengo informados de todo. ¡Gracias otra vez, majo!
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Ayuda para Convertir Todo este código en Function MaxiDucoli Internet 3 01-10-2017 23:29:07
Convertir cadena aleatoria en cadena de N caracteres DANY OOP 3 12-03-2009 21:49:21
Problemas para validar entrada de datos en delphi 7 Nelly Varios 1 28-03-2007 00:31:25
Tengo un lio con cierto código David OOP 11 13-10-2006 21:07:34
Concatenar Cadena Larga dentro de codigo Delphi JoanKa Conexión con bases de datos 6 04-03-2005 18:53:44


La franja horaria es GMT +2. Ahora son las 01:00:07.


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
Copyright 1996-2007 Club Delphi