Iniciar Sesión

Ver la Versión Completa : [Sintaxis] Calcular CRC8 en Cobol


Dasije
28 de septiembre de 2021, 18:43
Hola a tod@s.

Como calcular el valor CRC8 desde un campo de texto.

Os dejo el ejemplo en Delphi, también existe para Java y PHP, pero para COBOL no hay.

const
CRC8_Table: array[0..255] of Byte = (
$00, $07, $0E, $09, $1C, $1B, $12, $15,
$38, $3F, $36, $31, $24, $23, $2A, $2D,
$70, $77, $7E, $79, $6C, $6B, $62, $65,
$48, $4F, $46, $41, $54, $53, $5A, $5D,
$E0, $E7, $EE, $E9, $FC, $FB, $F2, $F5,
$D8, $DF, $D6, $D1, $C4, $C3, $CA, $CD,
$90, $97, $9E, $99, $8C, $8B, $82, $85,
$A8, $AF, $A6, $A1, $B4, $B3, $BA, $BD,
$C7, $C0, $C9, $CE, $DB, $DC, $D5, $D2,
$FF, $F8, $F1, $F6, $E3, $E4, $ED, $EA,
$B7, $B0, $B9, $BE, $AB, $AC, $A5, $A2,
$8F, $88, $81, $86, $93, $94, $9D, $9A,
$27, $20, $29, $2E, $3B, $3C, $35, $32,
$1F, $18, $11, $16, $03, $04, $0D, $0A,
$57, $50, $59, $5E, $4B, $4C, $45, $42,
$6F, $68, $61, $66, $73, $74, $7D, $7A,
$89, $8E, $87, $80, $95, $92, $9B, $9C,
$B1, $B6, $BF, $B8, $AD, $AA, $A3, $A4,
$F9, $FE, $F7, $F0, $E5, $E2, $EB, $EC,
$C1, $C6, $CF, $C8, $DD, $DA, $D3, $D4,
$69, $6E, $67, $60, $75, $72, $7B, $7C,
$51, $56, $5F, $58, $4D, $4A, $43, $44,
$19, $1E, $17, $10, $05, $02, $0B, $0C,
$21, $26, $2F, $28, $3D, $3A, $33, $34,
$4E, $49, $40, $47, $52, $55, $5C, $5B,
$76, $71, $78, $7F, $6A, $6D, $64, $63,
$3E, $39, $30, $37, $22, $25, $2C, $2B,
$06, $01, $08, $0F, $1A, $1D, $14, $13,
$AE, $A9, $A0, $A7, $B2, $B5, $BC, $BB,
$96, $91, $98, $9F, $8A, $8D, $84, $83,
$DE, $D9, $D0, $D7, $C2, $C5, $CC, $CB,
$E6, $E1, $E8, $EF, $FA, $FD, $F4, $F3);


function Calculate_CRC8(Cadena: String):String;
var
data: TArray;
len, i: Integer;
crc: byte;
begin
data := TEncoding.UTF8.GetBytes(Cadena);
len := Length(data);
crc := 0;

for i := 0 to len-1 do
crc := CRC8_Table[(crc xor data[i]) and $FF];

Result := Format('%.*d', [3, (crc and $FF)]);
end;

@Kuk,

Kuk
28 de septiembre de 2021, 20:27
@Dasije, hola amigo, hace mucho que no te vemos.

Quieres traducirlo a Cobol? O es un aporte en Delphi?

Dasije
28 de septiembre de 2021, 20:40
Hola Kuk.

Traducirlo a COBOL, aunque el ejemplo se entiende hasta cierto punto, pero hay cosas que no entiendo, como las variables como trabajan en DELPHI, sobre todo el TArray, si es numérico o no, como calcular el XOR, cosas que se me escapan de no haber trabajado con este compilador.

Gracias y saludos.

Kuk
29 de septiembre de 2021, 00:29
como calcular el XOR
Fujitsu: Chapter 10 Logical Operator Routines > 10.6 CBL_XOR (https://software.fujitsu.com/jp/manual/manualfiles/m150010/b1wd3360/01enz200/b3360-00-10-06-00.html)
MF: CBL_XOR (https://www.microfocus.com/documentation/extend-acucobol/925/BKPPPPLIBRS038.html)

@Dasije, tienes algún ejemplo de lo que le pasas y qué tiene que dar en la salida?


Ya no tengo el Fujitsu Cobol instalado, pero esto funciona en MF y debe funcionar en Fujitsu:


program-id. CRC as "CRC".

environment division.
configuration section.

data division.
working-storage section.

01 CRC8-Table.
05 filler occurs 256.
10 tb-char PIC X(1).

01 cadena PIC X(256) value "Hola amigo".
01 len PIC 9(4) COMP-5.
01 crc PIC X(1).
01 crcNum redefines crc pic 9(2) comp-5.

01 idx-1 PIC 9(4) COMP-5.

01 tmpChar PIC X(1).
01 tmpIdx redefines tmpChar pic 9(2) comp-5.

procedure division.

perform chargeTable
perform getLen

move 1 to idx-1

perform until idx-1 > len
move cadena(idx-1:1) to tmpChar

call "CBL_XOR" using crc tmpChar by value 1
call "CBL_AND" using X"FF" tmpChar by value 1

move tb-char(tmpIdx) to crc

add 1 to idx-1
end-perform

display crcNum

goback
.


chargeTable.
string X"00", X"07", X"0E", X"09", X"1C", X"1B",
X"12", X"15",
X"38", X"3F", X"36", X"31", X"24", X"23", X"2A", X"2D",
X"70", X"77", X"7E", X"79", X"6C", X"6B", X"62", X"65",
X"48", X"4F", X"46", X"41", X"54", X"53", X"5A", X"5D",
X"E0", X"E7", X"EE", X"E9", X"FC", X"FB", X"F2", X"F5",
X"D8", X"DF", X"D6", X"D1", X"C4", X"C3", X"CA", X"CD",
X"90", X"97", X"9E", X"99", X"8C", X"8B", X"82", X"85",
X"A8", X"AF", X"A6", X"A1", X"B4", X"B3", X"BA", X"BD",
X"C7", X"C0", X"C9", X"CE", X"DB", X"DC", X"D5", X"D2",
X"FF", X"F8", X"F1", X"F6", X"E3", X"E4", X"ED", X"EA",
X"B7", X"B0", X"B9", X"BE", X"AB", X"AC", X"A5", X"A2",
X"8F", X"88", X"81", X"86", X"93", X"94", X"9D", X"9A",
X"27", X"20", X"29", X"2E", X"3B", X"3C", X"35", X"32",
X"1F", X"18", X"11", X"16", X"03", X"04", X"0D", X"0A",
X"57", X"50", X"59", X"5E", X"4B", X"4C", X"45", X"42",
X"6F", X"68", X"61", X"66", X"73", X"74", X"7D", X"7A",
X"89", X"8E", X"87", X"80", X"95", X"92", X"9B", X"9C",
X"B1", X"B6", X"BF", X"B8", X"AD", X"AA", X"A3", X"A4",
X"F9", X"FE", X"F7", X"F0", X"E5", X"E2", X"EB", X"EC",
X"C1", X"C6", X"CF", X"C8", X"DD", X"DA", X"D3", X"D4",
X"69", X"6E", X"67", X"60", X"75", X"72", X"7B", X"7C",
X"51", X"56", X"5F", X"58", X"4D", X"4A", X"43", X"44",
X"19", X"1E", X"17", X"10", X"05", X"02", X"0B", X"0C",
X"21", X"26", X"2F", X"28", X"3D", X"3A", X"33", X"34",
X"4E", X"49", X"40", X"47", X"52", X"55", X"5C", X"5B",
X"76", X"71", X"78", X"7F", X"6A", X"6D", X"64", X"63",
X"3E", X"39", X"30", X"37", X"22", X"25", X"2C", X"2B",
X"06", X"01", X"08", X"0F", X"1A", X"1D", X"14", X"13",
X"AE", X"A9", X"A0", X"A7", X"B2", X"B5", X"BC", X"BB",
X"96", X"91", X"98", X"9F", X"8A", X"8D", X"84", X"83",
X"DE", X"D9", X"D0", X"D7", X"C2", X"C5", X"CC", X"CB",
X"E6", X"E1", X"E8", X"EF", X"FA", X"FD", X"F4", X"F3"
delimited by size into CRC8-Table
.

getLen.

move 10 to len

*> Fujitsu: function stored-cahr-length
*> Otros: un bucle, unstring con x"00" o NOT = SPACES etc.
.

end program CRC.



Para la cadena "Hola amigo" en la salida tengo 023 o lo que es lo mismo X'17'

Dasije
29 de septiembre de 2021, 18:16
Hola buenas tardes.

Lo he probado, y tiene errores al utilizar un string con determinadas letras, como ejemplo funciona correctamente.

Este es el string que tengo que utilizar:

TBAI-00000006Y-251019-btFpwP8dcLGAF-

Y el resultado debe ser: 237

Saludos.

Kuk
30 de septiembre de 2021, 11:15
@Dasije, estás seguro que el código Delphi es correcto?

En todo caso el XOR y AND en Cobol se hacen como en el ejemplo, o sea que tienes el mecanismo de cómo hacerlo. Puedes intentar partir de otro ejemplo.

Si te surgen más dudas, ya sabes ;)

JCantero
30 de septiembre de 2021, 14:27
@Kuk por curiosidad he probado tu ejemplo pero creo que no puede funcionar.


01 crc PIC X(1).
01 crcNum redefines crc pic 9(2) comp-5.


crcNum esta definido como pic 99 pero puede llegar a 256 con lo que hace falta un pic 999.

@Dasije, dame un ejemplo mas corto para poder comprobar. Con el ejemplo que indicas es demasiado largo para depurar.

La cadena
"TBAI-00000006Y-251019-btFpwP8dcLGAF-" me da 130
"Hola amigo" me da 153


Dame resultado para la cadena: "123" y poder depurar si hay algun error

Kuk
30 de septiembre de 2021, 16:03
@JCantero, es un COMP-5 o sea binario nativo y por lo tanto no obedece al PIC de Cobol sino al tamaño físico ;)

Para que te hagas una idea, declara un campo como PIC 9(4) COMP-5 y hazle un MOVE de 54321 y luego hazle un DISPLAY, ya verás :bien:

COMPUTATIONAL-5 or COMP-5 (native binary): Computational items (https://www.ibm.com/docs/en/cobol-zos/4.2?topic=clause-computational-items)

En cuanto al resultado: el problema de @Dasije eran las operaciones sobre Bits. En realidad, según lo que vi por los internetes, no estoy para nada seguro que el código Delphi es correcto. Por lo pronto la tabla difiere de las que he visto por ahí. Y el código pues también. Pero es lo de menos porque se puede jugar con ello hasta dar con lo que se desea o simplemente ver el algoritmo en sí y crear código propio.

JCantero
30 de septiembre de 2021, 16:26
es un COMP-5 o sea binario nativo y por lo tanto no obedece al PIC de Cobol sino al tamaño físico

En RM/Cobol un pic 99 es un numero de 2 digitos.

Si hago esto :


id division.
program-id. Comp5.

environment division.
configuration section.

data division.
working-storage section.


01 crc PIC X(1).
01 crcNum redefines crc pic 9(2) comp-5.


procedure division.
inicio.
move 205 to crcNum
display crcNum

STOP RUN.




El resultado del display es 05


He probado en OpenCobol y funciona igual.

Ya no se en otros cobol, pero en los que he probado es asi.

:losiento:

Kuk
30 de septiembre de 2021, 17:19
@JCantero, tendrás que poner una directiva de compilación porque seguramente los COMP-5 se traten de igual manera que los COMP (que son los binarios BigEndian, independientes de máquina y sí que obeden a las reglas PIC de Cobol).

En IBM, Fujitsu y MF los COMP-5 por defecto son binarios nativos.

---------- Post añadido : 17:19 ---------- Post anterior : 16:31 ----------

@JCantero,

Computational items (https://www.ibm.com/docs/en/cobol-zos/4.2?topic=clause-computational-items)

Digits in PICTURE clause|Storage occupied
1 through 4 |2 bytes (halfword)
5 through 9 |4 bytes (fullword)
10 through 18 |8 bytes (doubleword)

Dasije
30 de septiembre de 2021, 19:21
Hola @JCantero,

Te pago el código en Java, este es el ejemplo que ofrece la administración pública.

package net.ticketbai;
import java.io.UnsupportedEncodingException;
public class CRC8{
private static final String UTF_8 = "UTF-8";
// CRC-8,
// Poly = x^8 + x^2 + x^1 + x^0
// Init = 0
// RefIn = false
// RefOut = false
// XorOut = 0
private static final byte[] crc8_table =
new byte[] {
(byte) 0x00, (byte) 0x07, (byte) 0x0E, (byte) 0x09, (byte) 0x1C, (byte) 0x1B, (byte) 0x12, (byte) 0x15,
(byte) 0x38, (byte) 0x3F, (byte) 0x36, (byte) 0x31, (byte) 0x24, (byte) 0x23, (byte) 0x2A, (byte) 0x2D,
(byte) 0x70, (byte) 0x77, (byte) 0x7E, (byte) 0x79, (byte) 0x6C, (byte) 0x6B, (byte) 0x62, (byte) 0x65,
(byte) 0x48, (byte) 0x4F, (byte) 0x46, (byte) 0x41, (byte) 0x54, (byte) 0x53, (byte) 0x5A, (byte) 0x5D,
(byte) 0xE0, (byte) 0xE7, (byte) 0xEE, (byte) 0xE9, (byte) 0xFC, (byte) 0xFB, (byte) 0xF2, (byte) 0xF5,
(byte) 0xD8, (byte) 0xDF, (byte) 0xD6, (byte) 0xD1, (byte) 0xC4, (byte) 0xC3, (byte) 0xCA, (byte) 0xCD,
(byte) 0x90, (byte) 0x97, (byte) 0x9E, (byte) 0x99, (byte) 0x8C, (byte) 0x8B, (byte) 0x82, (byte) 0x85,
(byte) 0xA8, (byte) 0xAF, (byte) 0xA6, (byte) 0xA1, (byte) 0xB4, (byte) 0xB3, (byte) 0xBA, (byte) 0xBD,
(byte) 0xC7, (byte) 0xC0, (byte) 0xC9, (byte) 0xCE, (byte) 0xDB, (byte) 0xDC, (byte) 0xD5, (byte) 0xD2,
(byte) 0xFF, (byte) 0xF8, (byte) 0xF1, (byte) 0xF6, (byte) 0xE3, (byte) 0xE4, (byte) 0xED, (byte) 0xEA,
(byte) 0xB7, (byte) 0xB0, (byte) 0xB9, (byte) 0xBE, (byte) 0xAB, (byte) 0xAC, (byte) 0xA5, (byte) 0xA2,
(byte) 0x8F, (byte) 0x88, (byte) 0x81, (byte) 0x86, (byte) 0x93, (byte) 0x94, (byte) 0x9D, (byte) 0x9A,
(byte) 0x27, (byte) 0x20, (byte) 0x29, (byte) 0x2E, (byte) 0x3B, (byte) 0x3C, (byte) 0x35, (byte) 0x32,
(byte) 0x1F, (byte) 0x18, (byte) 0x11, (byte) 0x16, (byte) 0x03, (byte) 0x04, (byte) 0x0D, (byte) 0x0A,
(byte) 0x57, (byte) 0x50, (byte) 0x59, (byte) 0x5E, (byte) 0x4B, (byte) 0x4C, (byte) 0x45, (byte) 0x42,
(byte) 0x6F, (byte) 0x68, (byte) 0x61, (byte) 0x66, (byte) 0x73, (byte) 0x74, (byte) 0x7D, (byte) 0x7A,
(byte) 0x89, (byte) 0x8E, (byte) 0x87, (byte) 0x80, (byte) 0x95, (byte) 0x92, (byte) 0x9B, (byte) 0x9C,
(byte) 0xB1, (byte) 0xB6, (byte) 0xBF, (byte) 0xB8, (byte) 0xAD, (byte) 0xAA, (byte) 0xA3, (byte) 0xA4,
(byte) 0xF9, (byte) 0xFE, (byte) 0xF7, (byte) 0xF0, (byte) 0xE5, (byte) 0xE2, (byte) 0xEB, (byte) 0xEC,
(byte) 0xC1, (byte) 0xC6, (byte) 0xCF, (byte) 0xC8, (byte) 0xDD, (byte) 0xDA, (byte) 0xD3, (byte) 0xD4,
(byte) 0x69, (byte) 0x6E, (byte) 0x67, (byte) 0x60, (byte) 0x75, (byte) 0x72, (byte) 0x7B, (byte) 0x7C,
(byte) 0x51, (byte) 0x56, (byte) 0x5F, (byte) 0x58, (byte) 0x4D, (byte) 0x4A, (byte) 0x43, (byte) 0x44,
(byte) 0x19, (byte) 0x1E, (byte) 0x17, (byte) 0x10, (byte) 0x05, (byte) 0x02, (byte) 0x0B, (byte) 0x0C,
(byte) 0x21, (byte) 0x26, (byte) 0x2F, (byte) 0x28, (byte) 0x3D, (byte) 0x3A, (byte) 0x33, (byte) 0x34,
(byte) 0x4E, (byte) 0x49, (byte) 0x40, (byte) 0x47, (byte) 0x52, (byte) 0x55, (byte) 0x5C, (byte) 0x5B,
(byte) 0x76, (byte) 0x71, (byte) 0x78, (byte) 0x7F, (byte) 0x6A, (byte) 0x6D, (byte) 0x64, (byte) 0x63,
(byte) 0x3E, (byte) 0x39, (byte) 0x30, (byte) 0x37, (byte) 0x22, (byte) 0x25, (byte) 0x2C, (byte) 0x2B,
(byte) 0x06, (byte) 0x01, (byte) 0x08, (byte) 0x0F, (byte) 0x1A, (byte) 0x1D, (byte) 0x14, (byte) 0x13,
(byte) 0xAE, (byte) 0xA9, (byte) 0xA0, (byte) 0xA7, (byte) 0xB2, (byte) 0xB5, (byte) 0xBC, (byte) 0xBB,
(byte) 0x96, (byte) 0x91, (byte) 0x98, (byte) 0x9F, (byte) 0x8A, (byte) 0x8D, (byte) 0x84, (byte) 0x83,
(byte) 0xDE, (byte) 0xD9, (byte) 0xD0, (byte) 0xD7, (byte) 0xC2, (byte) 0xC5, (byte) 0xCC, (byte) 0xCB,
(byte) 0xE6, (byte) 0xE1, (byte) 0xE8, (byte) 0xEF, (byte) 0xFA, (byte) 0xFD, (byte) 0xF4, (byte) 0xF3 };
/**
* Calculate the CRC value with data from input string.
* @param input input string
* @return The calculated CRC value. Left padding with zeros.
* @throws UnsupportedEncodingException
*/
public static String calculate(String input) throws UnsupportedEncodingException {
byte[] data = input.getBytes(UTF_8);
int len = data.length;
byte crc = 0;
for (int i = 0; i < len; i++)
crc = crc8_table[(crc ^ data[i]) & 0xff];
return String.format("%03d", crc & 0xFFL);
}}

Fito
1 de octubre de 2021, 04:15
Hola Amigos:

Perdonen la ignorancia pero veo que esta instrucción que está en el codigo original, no está en el codigo cobol


data = input.getBytes(UTF_8);


Será por eso?

Saludos

Fito...

Kuk
1 de octubre de 2021, 15:47
@Dasije, aquí tienes un ejemplo funcionando:


$set sourceformat(variable)
program-id. CRC8 as "CRC8".

environment division.
configuration section.

data division.
working-storage section.

01 CRC8-Table.
05 filler occurs 256.
10 tbByte PIC X(1).
10 tbByteNum redefines tbByte PIC S9(2) COMP-5.

01 cadena PIC X(256) VALUE
"TBAI-00000006Y-251019-btFpwP8dcLGAF-".
01 len PIC 9(2) COMP-5.
01 crc PIC X(1).
01 crcNum redefines crc PIC 9(2) comp-5.
01 crcNumInt PIC S9(9) COMP-5.

01 idx-1 PIC 9(2) COMP-5.

01 tmpChar PIC X(1).
01 tmpIdx redefines tmpChar PIC S9(2) COMP-5.
01 tmpIdxInt PIC S9(9) COMP-5.

procedure division.

perform chargeTable
perform getLen

move 1 to idx-1
move 0 to crcNumInt

perform until idx-1 > len
move cadena(idx-1:1) to tmpChar
move tmpIdx to tmpIdxInt

call "CBL_XOR" using crcNumInt tmpIdxInt by value 4
display tmpIdxInt " " no advancing

call "CBL_AND" using X"FF000000" tmpIdxInt by value 4
display tmpIdxInt " "
tbByteNum(tmpIdxInt + 1) " " no advancing

move tbByte(tmpIdxInt + 1) to crc
move crcNum to crcNumInt

display crcNumInt " "

add 1 to idx-1
end-perform

call "CBL_AND" using X"FF000000" crcNumInt by value 4

display crcNumInt

move crcNumInt to crcNum

display crcNum " " crc

goback
.


chargeTable.
string
X"00", X"07", X"0E", X"09",
X"1C", X"1B", X"12", X"15", X"38", X"3F", X"36", X"31",
X"24", X"23", X"2A", X"2D", X"70", X"77", X"7E", X"79",
X"6C", X"6B", X"62", X"65", X"48", X"4F", X"46", X"41",

X"54", X"53", X"5A", X"5D", X"E0", X"E7", X"EE", X"E9",
X"FC", X"FB", X"F2", X"F5", X"D8", X"DF", X"D6", X"D1",
X"C4", X"C3", X"CA", X"CD", X"90", X"97", X"9E", X"99",
X"8C", X"8B", X"82", X"85", X"A8", X"AF", X"A6", X"A1",
X"B4", X"B3", X"BA", X"BD", X"C7", X"C0", X"C9", X"CE",
X"DB", X"DC", X"D5", X"D2", X"FF", X"F8", X"F1", X"F6",
X"E3", X"E4", X"ED", X"EA", X"B7", X"B0", X"B9", X"BE",
X"AB", X"AC", X"A5", X"A2", X"8F", X"88", X"81", X"86",
X"93", X"94", X"9D", X"9A", X"27", X"20", X"29", X"2E",
X"3B", X"3C", X"35", X"32", X"1F", X"18", X"11", X"16",
X"03", X"04", X"0D", X"0A", X"57", X"50", X"59", X"5E",
X"4B", X"4C", X"45", X"42", X"6F", X"68", X"61", X"66",
X"73", X"74", X"7D", X"7A", X"89", X"8E", X"87", X"80",
X"95", X"92", X"9B", X"9C", X"B1", X"B6", X"BF", X"B8",
X"AD", X"AA", X"A3", X"A4", X"F9", X"FE", X"F7", X"F0",
X"E5", X"E2", X"EB", X"EC", X"C1", X"C6", X"CF", X"C8",
X"DD", X"DA", X"D3", X"D4", X"69", X"6E", X"67", X"60",
X"75", X"72", X"7B", X"7C", X"51", X"56", X"5F", X"58",
X"4D", X"4A", X"43", X"44", X"19", X"1E", X"17", X"10",
X"05", X"02", X"0B", X"0C", X"21", X"26", X"2F", X"28",
X"3D", X"3A", X"33", X"34", X"4E", X"49", X"40", X"47",
X"52", X"55", X"5C", X"5B", X"76", X"71", X"78", X"7F",
X"6A", X"6D", X"64", X"63", X"3E", X"39", X"30", X"37",
X"22", X"25", X"2C", X"2B", X"06", X"01", X"08", X"0F",
X"1A", X"1D", X"14", X"13", X"AE", X"A9", X"A0", X"A7",
X"B2", X"B5", X"BC", X"BB", X"96", X"91", X"98", X"9F",
X"8A", X"8D", X"84", X"83", X"DE", X"D9", X"D0", X"D7",
X"C2", X"C5", X"CC", X"CB", X"E6", X"E1", X"E8", X"EF",
X"FA", X"FD", X"F4", X"F3"
delimited by size into CRC8-Table
.

getLen.

move 36 to len

*> Fujitsu: function stored-cahr-length
*> Otros: un bucle, unstring con x"00" o NOT = SPACES etc.
.

end program CRC8.



Salida de tu codigo Java:

84 84 -85 -85
-23 233 -111 -111
-48 208 62 62
119 119 66 66
111 111 10 10
58 58 -90 -90
-106 150 -21 -21
-37 219 15 15
63 63 -67 -67
-115 141 -86 -86
-102 154 -49 -49
-1 255 -13 -13
-59 197 85 85
12 12 36 36
9 9 63 63
13 13 35 35
22 22 98 98
83 83 -66 -66
-114 142 -93 -93
-110 146 -9 -9
-50 206 100 100
73 73 -8 -8
-102 154 -49 -49
-69 187 40 40
110 110 13 13
125 125 116 116
3 3 9 9
89 89 -120 -120
-80 176 25 25
125 125 116 116
23 23 101 101
41 41 -33 -33
-104 152 -63 -63
-128 128 -119 -119
-49 207 99 99
78 78 -19 -19
-19 237
237



Salida del programa Cobol:

+0000000084 +0000000084 -085 +0000000171
+0000000233 +0000000233 -111 +0000000145
+0000000208 +0000000208 +062 +0000000062
+0000000119 +0000000119 +066 +0000000066
+0000000111 +0000000111 +010 +0000000010
+0000000058 +0000000058 -090 +0000000166
+0000000150 +0000000150 -021 +0000000235
+0000000219 +0000000219 +015 +0000000015
+0000000063 +0000000063 -067 +0000000189
+0000000141 +0000000141 -086 +0000000170
+0000000154 +0000000154 -049 +0000000207
+0000000255 +0000000255 -013 +0000000243
+0000000197 +0000000197 +085 +0000000085
+0000000012 +0000000012 +036 +0000000036
+0000000009 +0000000009 +063 +0000000063
+0000000013 +0000000013 +035 +0000000035
+0000000022 +0000000022 +098 +0000000098
+0000000083 +0000000083 -066 +0000000190
+0000000142 +0000000142 -093 +0000000163
+0000000146 +0000000146 -009 +0000000247
+0000000206 +0000000206 +100 +0000000100
+0000000073 +0000000073 -008 +0000000248
+0000000154 +0000000154 -049 +0000000207
+0000000187 +0000000187 +040 +0000000040
+0000000110 +0000000110 +013 +0000000013
+0000000125 +0000000125 +116 +0000000116
+0000000003 +0000000003 +009 +0000000009
+0000000089 +0000000089 -120 +0000000136
+0000000176 +0000000176 +025 +0000000025
+0000000125 +0000000125 +116 +0000000116
+0000000023 +0000000023 +101 +0000000101
+0000000041 +0000000041 -033 +0000000223
+0000000152 +0000000152 -063 +0000000193
+0000000128 +0000000128 -119 +0000000137
+0000000207 +0000000207 +099 +0000000099
+0000000078 +0000000078 -019 +0000000237
+0000000237
237 Ý


Se puede retrabajarlo y eso pero bueno, ya te lo dejo a ti. Funcionar funciona.

---------- Post añadido : 15:07 ---------- Post anterior : 15:04 ----------

@Fito, esto nos da igual amigo, borque hablamos de Bytes tal cual ;)

El problema es que en Java, Delphi etc las tablas o los Arrays empiezan por el indice 0 y en Cobol en 1.
El código saca el indice de la tabla definida de valores, con lo cual para Cobol hay que hacerle + 1

---------- Post añadido : 15:47 ---------- Post anterior : 15:07 ----------

@Dasije, versión retrabajada:


$set sourceformat(variable)
program-id. CRC8 as "CRC8".

environment division.
configuration section.

data division.
working-storage section.

01 CRC8-Table.
05 filler occurs 256.
10 tbByte PIC X(1).

01 cadena PIC X(256) VALUE
"TBAI-00000006Y-251019-btFpwP8dcLGAF-".
01 len PIC 9(2) COMP-5.
01 crc PIC X(1).
01 crcNum redefines crc PIC 9(2) comp-5.

01 idx-1 PIC 9(2) COMP-5.

01 tmpChar PIC X(1).
01 tmpIdx redefines tmpChar PIC 9(2) COMP-5.

procedure division.

perform chargeTable
perform getLen

move 1 to idx-1
move 0 to crcNum

perform until idx-1 > len
move cadena(idx-1:1) to tmpChar

call "CBL_XOR" using crcNum tmpIdx by value 1
call "CBL_AND" using X"FF" tmpIdx by value 1

move tbByte(tmpIdx + 1) to crc

add 1 to idx-1
end-perform

call "CBL_AND" using X"FF" crcNum by value 1

display crcNum

goback
.


chargeTable.
string
X"00", X"07", X"0E", X"09",
X"1C", X"1B", X"12", X"15", X"38", X"3F", X"36", X"31",
X"24", X"23", X"2A", X"2D", X"70", X"77", X"7E", X"79",
X"6C", X"6B", X"62", X"65", X"48", X"4F", X"46", X"41",

X"54", X"53", X"5A", X"5D", X"E0", X"E7", X"EE", X"E9",
X"FC", X"FB", X"F2", X"F5", X"D8", X"DF", X"D6", X"D1",
X"C4", X"C3", X"CA", X"CD", X"90", X"97", X"9E", X"99",
X"8C", X"8B", X"82", X"85", X"A8", X"AF", X"A6", X"A1",
X"B4", X"B3", X"BA", X"BD", X"C7", X"C0", X"C9", X"CE",
X"DB", X"DC", X"D5", X"D2", X"FF", X"F8", X"F1", X"F6",
X"E3", X"E4", X"ED", X"EA", X"B7", X"B0", X"B9", X"BE",
X"AB", X"AC", X"A5", X"A2", X"8F", X"88", X"81", X"86",
X"93", X"94", X"9D", X"9A", X"27", X"20", X"29", X"2E",
X"3B", X"3C", X"35", X"32", X"1F", X"18", X"11", X"16",
X"03", X"04", X"0D", X"0A", X"57", X"50", X"59", X"5E",
X"4B", X"4C", X"45", X"42", X"6F", X"68", X"61", X"66",
X"73", X"74", X"7D", X"7A", X"89", X"8E", X"87", X"80",
X"95", X"92", X"9B", X"9C", X"B1", X"B6", X"BF", X"B8",
X"AD", X"AA", X"A3", X"A4", X"F9", X"FE", X"F7", X"F0",
X"E5", X"E2", X"EB", X"EC", X"C1", X"C6", X"CF", X"C8",
X"DD", X"DA", X"D3", X"D4", X"69", X"6E", X"67", X"60",
X"75", X"72", X"7B", X"7C", X"51", X"56", X"5F", X"58",
X"4D", X"4A", X"43", X"44", X"19", X"1E", X"17", X"10",
X"05", X"02", X"0B", X"0C", X"21", X"26", X"2F", X"28",
X"3D", X"3A", X"33", X"34", X"4E", X"49", X"40", X"47",
X"52", X"55", X"5C", X"5B", X"76", X"71", X"78", X"7F",
X"6A", X"6D", X"64", X"63", X"3E", X"39", X"30", X"37",
X"22", X"25", X"2C", X"2B", X"06", X"01", X"08", X"0F",
X"1A", X"1D", X"14", X"13", X"AE", X"A9", X"A0", X"A7",
X"B2", X"B5", X"BC", X"BB", X"96", X"91", X"98", X"9F",
X"8A", X"8D", X"84", X"83", X"DE", X"D9", X"D0", X"D7",
X"C2", X"C5", X"CC", X"CB", X"E6", X"E1", X"E8", X"EF",
X"FA", X"FD", X"F4", X"F3"
delimited by size into CRC8-Table
.

getLen.

move 36 to len

*> Fujitsu: function stored-cahr-length
*> Otros: un bucle, unstring con x"00" o NOT = SPACES etc.
.

end program CRC8.

JCantero
2 de octubre de 2021, 01:20
Esto parece competicion
cadena "123"
Resultado ?

Kuk
2 de octubre de 2021, 01:28
cadena "123"
Resultado ?

Me da 192

---------- Post añadido : 01:28 ---------- Post anterior : 01:26 ----------

@JCantero, por cierto, por lo visto RM/Cobol simplemente NO TIENE campos binarios......
Una flipada la verdad....
Converting RM/COBOL Data Files (https://www.microfocus.com/documentation/object-cobol/ocu42/cg3dat.htm)

Dasije
2 de octubre de 2021, 12:33
Hola @Kuk.

He probado el ejemplo ultimo, el que está más trabajado, y funciona correctamente en NetExpress 3.1

En NetCOBOL funciona, pero no da el resultado correcto, da 37, creo que tiene que ver el tamaño numérico en las variables.

Saludos y gracias.

JCantero
2 de octubre de 2021, 16:09
@Kuk, En RM/Cobol puse crcNUM como pic 9(3) en vez de pic 9(2) y da el mismo resultado.

:acuer:

Kuk
2 de octubre de 2021, 18:44
@Dasije, para Fujitsu, intenta poner la directiva BINARY(BYTE) a ver qué tal. Si no, también prueba el ejemplo de más arriba, el que usa Integers en vez de Bytes y mira a ver si es correcto.
@Nitzer, tú qué opinas?

@JCantero, las operaciones de bits no pueden funcionar con el PIC 9(3) de Cobol, es decir hasta el valor 999. Si funciona, será que hay alguna transformación implícita por el Run-Time de RM.

JCantero
2 de octubre de 2021, 21:54
@Kuk, Pagina curiosa.

https://paiza.io/projects/G4cdZbJJniTkugqeAOXZZw

Tiene treinta y tantos lenguajes, entre ellos el cobol.

Tu ejemplo en cobol funciona perfectamente.


El que desee, puede hacer pruebas en cualquier dispositivo, movil, tablet, sin tener compilador ni runtime


:astro:

Kuk
2 de octubre de 2021, 22:22
@JCantero, en GNU Cobol funciona también.

Míralo aquí: Online COBOL Compiler - Online COBOL Editor - Run COBOL Online - Online COBOL Runner (https://www.jdoodle.com/execute-cobol-online/)

Dasije
3 de octubre de 2021, 21:38
Hola @Kuk.

Te dejo el código para NetCOBOL, no hacía falta la directiva para el binario, pero si mover el resultado una PIC 9(3) sin COMP-5, a pelo, entonces si se ve correctamente el resultado, cosas del compilador.

program-id. "CRC8".

environment division.
configuration section.

data division.
working-storage section.

01 CRC8-Table.
05 filler occurs 256.
10 tbByte PIC X(1).

01 cadena PIC X(256) VALUE
"https://batuz.eus/QRTBAI/?id=TBAI-00000006Y-251019-btFpwP8dcLGAF-237&s=T&nf=27174&i=4.70".
01 len PIC 9(2) COMP-5.
01 crc PIC X(1).
01 crcNum redefines crc PIC 9(2) comp-5.

01 crc_resultado PIC 9(3) VALUE ZEROS.

01 idx-1 PIC 9(2) COMP-5.

01 tmpChar PIC X(1).
01 tmpIdx redefines tmpChar PIC 9(2) COMP-5.

01 valor_XOR_AND PIC X(1) VALUE X"FF".

procedure division.

perform chargeTable
perform getLen

move 1 to idx-1
move 0 to crcNum

perform until idx-1 > len
move cadena(idx-1:1) to tmpChar

call "CBL_XOR" using crcNum tmpIdx by value 1
call "CBL_AND" using valor_XOR_AND tmpIdx by value 1

move tbByte(tmpIdx + 1) to crc

add 1 to idx-1
end-perform

call "CBL_AND" using valor_XOR_AND crcNum by value 1

move crcNum to crc_resultado

display crc_resultado

goback.

chargeTable.
string X"00", X"07", X"0E", X"09", X"1C", X"1B", X"12",
X"15", X"38", X"3F", X"36", X"31", X"24", X"23",
X"2A", X"2D", X"70", X"77", X"7E", X"79", X"6C",
X"6B", X"62", X"65", X"48", X"4F", X"46", X"41",
X"54", X"53", X"5A", X"5D", X"E0", X"E7", X"EE",
X"E9", X"FC", X"FB", X"F2", X"F5", X"D8", X"DF",
X"D6", X"D1", X"C4", X"C3", X"CA", X"CD", X"90",
X"97", X"9E", X"99", X"8C", X"8B", X"82", X"85",
X"A8", X"AF", X"A6", X"A1", X"B4", X"B3", X"BA",
X"BD", X"C7", X"C0", X"C9", X"CE", X"DB", X"DC",
X"D5", X"D2", X"FF", X"F8", X"F1", X"F6", X"E3",
X"E4", X"ED", X"EA", X"B7", X"B0", X"B9", X"BE",
X"AB", X"AC", X"A5", X"A2", X"8F", X"88", X"81",
X"86", X"93", X"94", X"9D", X"9A", X"27", X"20",
X"29", X"2E", X"3B", X"3C", X"35", X"32", X"1F",
X"18", X"11", X"16", X"03", X"04", X"0D", X"0A",
X"57", X"50", X"59", X"5E", X"4B", X"4C", X"45",
X"42", X"6F", X"68", X"61", X"66", X"73", X"74",
X"7D", X"7A", X"89", X"8E", X"87", X"80", X"95",
X"92", X"9B", X"9C", X"B1", X"B6", X"BF", X"B8",
X"AD", X"AA", X"A3", X"A4", X"F9", X"FE", X"F7",
X"F0", X"E5", X"E2", X"EB", X"EC", X"C1", X"C6",
X"CF", X"C8", X"DD", X"DA", X"D3", X"D4", X"69",
X"6E", X"67", X"60", X"75", X"72", X"7B", X"7C",
X"51", X"56", X"5F", X"58", X"4D", X"4A", X"43",
X"44", X"19", X"1E", X"17", X"10", X"05", X"02",
X"0B", X"0C", X"21", X"26", X"2F", X"28", X"3D",
X"3A", X"33", X"34", X"4E", X"49", X"40", X"47",
X"52", X"55", X"5C", X"5B", X"76", X"71", X"78",
X"7F", X"6A", X"6D", X"64", X"63", X"3E", X"39",
X"30", X"37", X"22", X"25", X"2C", X"2B", X"06",
X"01", X"08", X"0F", X"1A", X"1D", X"14", X"13",
X"AE", X"A9", X"A0", X"A7", X"B2", X"B5", X"BC",
X"BB", X"96", X"91", X"98", X"9F", X"8A", X"8D",
X"84", X"83", X"DE", X"D9", X"D0", X"D7", X"C2",
X"C5", X"CC", X"CB", X"E6", X"E1", X"E8", X"EF",
X"FA", X"FD", X"F4", X"F3"
delimited by size into CRC8-Table.

getLen.

move 88 to len

*> Fujitsu: function stored-cahr-length
*> Otros: un bucle, unstring con x"00" o NOT = SPACES etc.
.

end program CRC8.

El resultado en este caso debe ser 007 por tener otro string diferente, compruébalo en el ejemplo de Java, y así debe ser.

He comprobado los compiladores online, en ambos casos funciona correctamente.

Saludos y gracias.

Kuk
3 de octubre de 2021, 23:03
@Dasije, en Java da 007 también :bien: