Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Go Back   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Register FAQ Members List Calendar Guía de estilo Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 17/02/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
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:

Code:
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:

Quote:
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
Reply With Quote
  #2  
Old 17/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
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:
PHP Code:
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.

Last edited by escafandra : 18/02/2020 at 00:02.
Reply With Quote
  #3  
Old 18/02/2020
mamcx's Avatar
mamcx mamcx is offline
Moderador
 
Join Date: Sep 2004
Location: Medellín - Colombia
Posts: 3,941
Poder: 27
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Quote:
Originally Posted by dec View Post
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.

Last edited by mamcx : 18/02/2020 at 02:58.
Reply With Quote
  #4  
Old 18/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quote:
Originally Posted by mamcx View Post
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.
Reply With Quote
  #5  
Old 18/02/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
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
Reply With Quote
  #6  
Old 18/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Por si te sirve de ayuda, inicializando crc = 3077 da el resultado esperado.

Saludos.
Reply With Quote
  #7  
Old 18/02/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Quote:
Originally Posted by escafandra View Post
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
Reply With Quote
  #8  
Old 18/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quote:
Originally Posted by dec View Post
Hola a todos,



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!

A favor de 3077 (0C06h) es que es el único número de 0 - 65535 que consigue que CRC sea 5320 para el algoritmo implementado


Saludos.
Reply With Quote
  #9  
Old 18/02/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Quote:
Originally Posted by escafandra View Post
A favor de 3077 (0C06h) es que es el único número de 0 - 65535 que consigue que CRC sea 5320 para el algoritmo implementado


Saludos.
Je je je... vaya, que los has probado todos... Ya está comunicado esto al interesado... estamos aquí comunicándonos entre varios: ahora tengo que esperar la respuesta que le den a quien yo he contactado... Ciertamente, el 3077 tiene no poco a favor... sin embargo, aquí hay varias dudas: tal vez sea ese número el que haya que usar para inicializar la variable "crc", empero, se hace raro, entonces, que no lo mencionasen. Por lo demás, mencionan cierta documentación, que, luego parece no tener nada que ver... o sea... vamos a ver en qué queda todo esto. ¡Yo publicaré aquí lo que sea al final! Y muchas gracias de nuevo, escafandra, por tu interés y ayuda.
__________________
David Esperalta
www.decsoftutils.com
Reply With Quote
  #10  
Old 18/02/2020
orodriguezca orodriguezca is offline
Miembro
 
Join Date: Jan 2009
Posts: 221
Poder: 18
orodriguezca Va por buen camino
Dec, ¿Cual versión de Delphi estas utilizando?. Al migrar algoritmos similares desde Delphi 5 a Delphi XE3 ha sido necesario cambiar el tipo de datos de la variable que contiene la DATA de "String" a "AnsiString".


PostData: Ya hice la prueba y en este caso el cambiar a Ansistring no afecta el comportamiento.

Last edited by orodriguezca : 18/02/2020 at 20:06.
Reply With Quote
  #11  
Old 18/02/2020
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola David.

Aunque tarde, por que ya el trabajo está hecho, te pongo los códigos que usé para mis pruebas.

C++
PHP Code:
...
#define USHORT unsigned short
...

int crc16(const string &dataUSHORT crc)
{
  
USHORT x(0);
  
int count data.length();

  while (--
count >= 0)
  {
    
USHORT z = (USHORT)(data[x++] << 8);
    
crc = (USHORT)(crc z);
    for(
int i 80; --i)
      
crc = (crc 0x8000) ? (USHORT)(crc << 0x1021) : (USHORT)(crc << 1);
  }
    return 
crc;
}

void main()
{
  
string data "13|0000123|1|Maximilian|Mustermann|05051999|21092019";

  
cout <<  crc16(data3077) << endl
Delphi:
Código Delphi [-]

function Crc16(const data: string; crc: Word): Word;
var
  x, z: Word;
  count, i: Integer;
begin
  count := Pred(data.Length);
  x     := 0;
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;
  Result := crc;
end;

...
var
  data : string;
begin
  data :=  '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  ShowMessage(Crc16(data,3077).ToString);
end;

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Last edited by ecfisa : 18/02/2020 at 20:57.
Reply With Quote
  #12  
Old 18/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quote:
Originally Posted by ecfisa View Post
Hola David.

Aunque tarde, por que ya el trabajo está hecho, te pongo los códigos que usé para mis pruebas.

C++
PHP Code:
...
#define USHORT unsigned short
...

int crc16(const string &dataUSHORT crc)
{
  
USHORT x(0);
  
int count data.length();

  while (--
count >= 0)
  {
    
USHORT z = (USHORT)(data[x++] << 8);
    
crc = (USHORT)(crc z);
    for(
int i 80; --i)
      
crc = (crc 0x8000) ? (USHORT)(crc << 0x1021) : (USHORT)(crc << 1);
  }
    return 
crc;
}

void main()
{
  
string data "13|0000123|1|Maximilian|Mustermann|05051999|21092019";

  
cout <<  crc16(data3077) << endl
Delphi:


Código Delphi [-]
function Crc16(const data: string; crc: Word): Word;
var
  x, z: Word;
  count, i: Integer;
begin
  count := Pred(data.Length);
  x     := 0;
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;
  Result := crc;
end;

...
var
  data : string;
begin
  data :=  '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  ShowMessage(Crc16(data,3077).ToString);
end;


Saludos



La versión C++ funciona Ok pero la delphi tiene un pequeño error. El bucle principal debe ser:
Código Delphi [-]
while (count > 0)

Esto se debe a que en la versión C primero decrementa y en la delphi es después. Posiblemente ha sido que has publicado un código no terminado en lugar del final.



Saludos.
Reply With Quote
  #13  
Old 19/02/2020
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola escafandra.

Fijate que en la línea en que obtengo la longitud de cadena hago uso de la función Pred.

Dado el valor 3077, tanto la versión de C++ como la de Delphi 10.3 arrojan el resultado 5320.


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Last edited by ecfisa : 19/02/2020 at 05:23.
Reply With Quote
  #14  
Old 19/02/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Correcto.

Saludos.
Reply With Quote
  #15  
Old 19/02/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Quote:
Originally Posted by orodriguezca View Post
Dec, ¿Cual versión de Delphi estas utilizando?. Al migrar algoritmos similares desde Delphi 5 a Delphi XE3 ha sido necesario cambiar el tipo de datos de la variable que contiene la DATA de "String" a "AnsiString".


PostData: Ya hice la prueba y en este caso el cambiar a Ansistring no afecta el comportamiento.
Pues llevas razón orodriguezca, interesaba saber la versión de Delphi de que se trataba y se me olvidó mencionarlo, porque, además en este caso en concreto habré de usar Delphi 2007 como un requisito, es decir, no puedo usar versiones superiores, porque lo que se piensa llevar a cabo es cierto "plugin" que funciona dentro de un programa que no permite plugins "unicode", o sea, no permite plugins hechos con versiones de Delphi superiores a la 2007.

Gracias de nuevo a todos, ecfisa, escafandra, mamcx, en efecto, estoy esperando a ver qué me dicen sobre la necesidad de inicializar la variable "crc" con el valor "3077"... pues de otra forma no parece obtenerse el valor apropiado. Sea como sea, estoy seguro de que algo falla / falta en el código de ejemplo que me ofrecieron, es decir, vosotros no falláis, eso lo tengo claro: de modo que veremos a ver en qué queda todo esto. ¡En cuanto me digan algo lo publico aquí!
__________________
David Esperalta
www.decsoftutils.com
Reply With Quote
  #16  
Old 05/03/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Por fin he conseguido más información sobre el tema que se trata aquí... y ahora estoy seguro de que es posible convertir el código a Delphi, vaya, de que vosotros sabréis hacerlo, puesto que yo, aunque lo he intentado... no he sido capaz...

En efecto, el código de que se partía al principio no estaba completo, sino que faltaba información, según lo veo yo, principalmente, los tipos de las variables de entrada y de salida, o bien podía deducirse todo del siguiente código... que es el "programa" completo:

Code:
using System;
using System.Text;

namespace QRCode
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] b = Encoding.Default.GetBytes("13|0000123|1|Maximilian|Mustermann|05051999|21092019");

            byte[] crc = CCITTx1D0F(b, b.Length);

            // Podemos ver una salida = 5320, que, es la esperada para la cadena de entrada
            Console.WriteLine( $"{crc[0]:X2}{crc[1]:X2}" );

            Console.ReadLine();
        }
        
        static private byte[] CCITTx1D0F(byte[] data, int len)
        {
            int i, x = 0;
            ushort crc = 0x1D0F;
            int count = len;

            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);
            }
            return BitConverter.GetBytes(crc);
        }
    }
}
Como se ve, la cosa cambia... tratamos con "bytes", no con "words" o "strings", y, ahora sí, creo que podréis acaso ayudarme / convertir el código / solucionar el problema... ¡o eso espero, puesto que yo, aunque lo he intentado (¡y teniendo más de la mitad hecho!) me declaro incapaz... aunque voy a seguir intentándolo...

Desde ya os agradezco vuestra ayuda a todos.
__________________
David Esperalta
www.decsoftutils.com
Reply With Quote
  #17  
Old 05/03/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos de nuevo,

Quería añadir... que, en este caso, es importante tener en cuenta que la versión de Delphi habrá de ser la Delphi 2007... por si hay que tenerlo en cuenta...
__________________
David Esperalta
www.decsoftutils.com
Reply With Quote
  #18  
Old 05/03/2020
dec's Avatar
dec dec is offline
Moderador
 
Join Date: Dec 2004
Location: Alcobendas, Madrid, España
Posts: 13,142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola a todos,

Aquí los intentos que llevo a cabo, usando tanto el código de escafandra como el de ecfisa, dando ambos el mismo resultado: 22586, pero, no el esperado: 5320, la madre que le parió.

Código Delphi [-]
function StrToBytes(const Value: string): TBytes;
var
  I: integer;
begin
  SetLength(Result, Length(Value));
  Move(Value[1], Result[0], Length(Value));
end;

function WordToBytes(const Value: Word): TBytes;
begin
 SetLength(Result, 2);
 Result[0] := TBytes(@Value)[0];
 Result[1] := TBytes(@Value)[1];
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x, z: Word;
  crc: Word;
  count, i: Integer;
  Input: string;
  Data, Result: TBytes;
begin
  Input := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  
  Data := StrToBytes(Input);

  x := 0;
  crc := $1D0F;
  count := Pred(Length(Data));
  while (count >= 0) do
  begin
    Dec(count);
    Inc(x);
    z   := Word(Data[x]) shl 8;
    crc := crc xor z;
    for i := 7 downto 0 do
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
  end;

  Result := WordToBytes(crc);

  ShowMessageFmt('%d%d', [Result[0], Result[1]]);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: TBytes;
  i, x: Integer;
  z: WORD;
  CRC: WORD;
  SLength, n: Integer;
  Result: TBytes;
  Input: string;
begin
  Input := '13|0000123|1|Maximilian|Mustermann|05051999|21092019';

  S := StrToBytes(Input);

  CRC := $1D0F;
  SLength := Length(S);
  X := 1;
  while SLength > 0 do
  begin
    Z := 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 := WordToBytes(CRC);

  ShowMessageFmt('%d%d', [Result[0], Result[1]]);
end;
__________________
David Esperalta
www.decsoftutils.com
Reply With Quote
  #19  
Old 05/03/2020
ecfisa's Avatar
ecfisa ecfisa is offline
Moderador
 
Join Date: Dec 2005
Location: Tres Arroyos, Argentina
Posts: 10,508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola David.

A ver si entendí bien, ¿ El resultado esperado es 5320 ? por que de ser así el codigo que probé anteriormente me da ese resultado, no obtengo el valor 22586.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Reply With Quote
  #20  
Old 05/03/2020
escafandra's Avatar
[escafandra] escafandra is offline
Miembro Premium
 
Join Date: Nov 2007
Posts: 2,211
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Traducción cuasi literal:


Código Delphi [-]
type
ABYTE = array [0..1] of BYTE;
PABYTE = ^ABYTE;

function CCITTx1D0F(data: PAnsiChar; count: integer): ABYTE;
var
  crc, z: Word;
  x, i: Integer;
begin
  crc:= $1D0F;
  x     := 0;
  while (count > 0) do
  begin
    Dec(count);
    z   := Word(data[x]) shl 8;
    Inc(x);
    crc := crc xor z;
    i:=8;
    repeat
      if crc and $8000 <> 0 then
        crc := (crc shl 1 xor $1021)
      else
        crc := (crc shl 1);
      dec(i);
    until i<=0;
  end;
  Result := PABYTE(@crc)^;
end;


Uso:
Código Delphi [-]
var
  S: String;
  CRC: ABYTE;
begin
  S:= '13|0000123|1|Maximilian|Mustermann|05051999|21092019';
  CRC:= CCITTx1D0F(PAnsiChar(S), Length(S));
end;


Consideraciones:
1. En C un array de Char es una cadena. Un unsigned char es un BYTE. Con estas consideraciones y teniendo en cuenta que se introduce una cadena, podemos usar PAnsyChar como parametro de entrada. Tambien podríamos unsa un array de bytes pero requeriría casting de entrada.
2. el CRC es un word pasado a array de 2 Bytes. El resultado del word es 8275 que en hexadecimal es $2053 pero visto como array de bytes es $53, $20


Saludos.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Ayuda para Convertir Todo este código en Function MaxiDucoli Internet 3 01/10/2017 22:29
Convertir cadena aleatoria en cadena de N caracteres DANY OOP 3 12/03/2009 20:49
Problemas para validar entrada de datos en delphi 7 Nelly Varios 1 27/03/2007 23:31
Tengo un lio con cierto código David OOP 11 13/10/2006 20:07
Concatenar Cadena Larga dentro de codigo Delphi JoanKa Conexión con bases de datos 6 04/03/2005 17:53


All times are GMT +2. The time now is 02:16.


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