Créditos
Este desafío se originó en @miles .
Cree una función que calcule el hash CRC32 de una cadena de entrada. La entrada será una cadena ASCII de cualquier longitud. La salida será el hash CRC32 de esa cadena de entrada.
Explicación
El algoritmo de CRC32 y otros CRC son esencialmente los mismos, por lo que aquí solo se demostrará CRC3.
En primer lugar, tiene el polinomio generador, que en realidad es un entero de 4 bits [n + 1] (sería 33 bits en CRC32).
En este ejemplo, el polinomio generador es 1101
.
Luego, tendrá la cadena para hacer hash, que en este ejemplo sería 00010010111100101011001101
.
00010010111100101011001101|000 (1) append three [n] "0"s
1101 (2) align with highest bit
00001000111100101011001101|000 (3) XOR (1) and (2)
1101 (4) align with highest bit
00000101111100101011001101|000 (5) XOR (3) and (4)
1101 (6) align with highest bit
00000011011100101011001101|000 (7) XOR (5) and (6)
1101 (8) align with highest bit
00000000001100101011001101|000 (9) XOR (7) and (8)
1101 (10) align with highest bit
00000000000001101011001101|000 (11) XOR (9) and (10)
1101 (12) align with highest bit
00000000000000000011001101|000 (13) XOR (11) and (12)
1101 (14) align with highest bit
00000000000000000000011101|000 (15) XOR (13) and (14)
1101 (16) align with highest bit
00000000000000000000000111|000 (17) XOR (15) and (16)
110 1 (18) align with highest bit
00000000000000000000000001|100 (19) XOR (17) and (18)
1 101 (20) align with highest bit
00000000000000000000000000|001 (21) XOR (19) and (20)
^--------REGION 1--------^ ^2^
El resto obtenido en (21)
, cuando la región 1 es cero, es decir 001
, sería el resultado del hash CRC3.
Especificaciones
- El polinomio generador es
0x104C11DB7
, o0b100000100110000010001110110110111
, o4374732215
. - La entrada puede ser una cadena o una lista de enteros, o cualquier otro formato razonable.
- La salida puede ser una cadena hexadecimal o simplemente un número entero, o cualquier otro formato razonable.
- Los elementos integrados que calculan el hash CRC32 no están permitidos.
Objetivo
Se aplican las reglas estándar para el código de golf .
El código más corto gana.
Casos de prueba
input output (hex)
"code-golf" 147743960 08CE64D8
"jelly" 1699969158 65537886
"" 0 00000000
Respuestas:
Intel x86,
34302927 bytesToma la dirección de la cadena terminada en cero en ESI y devuelve el CRC en EBX:
Desmontaje (sintaxis de AT&T):
Incorporando sugerencias de Peter Cordes para guardar cuatro bytes más. Esto supone una convención de llamada donde el indicador de dirección para las instrucciones de cadena se borra en la entrada.
Incorporación de la sugerencia de Peter Ferrie de usar push literal y pop para cargar una constante, guardando un byte.
Incorporando la sugerencia de Peter Ferrie de saltar al segundo byte de una
xorl %eax, %ebx
instrucción que es unaretl
instrucción, combinada con cambiar la interfaz de la rutina para tomar una cadena terminada en cero en lugar de longitud, ahorrando dos bytes en total.fuente
cld
insn (como hice en mi respuesta adler32 ). ¿Es una práctica normal permitir convenciones de llamadas totalmente arbitrarias para respuestas asm?edi
y el puntero adentroesi
(tal vez no sea de extensión cero, así que tal vez evite las cosas y requiera un Puntero de 64 bits con extensión cero). (x32 para que pueda usar matemática de puntero de 32 bits de forma segura, pero aún tenga la convención de llamadas de registro-argumentos. Como no usainc
, no hay inconveniente en el modo largo.)edx
en orden de byte invertido?bswap edx
es solo 2B.shr %edx
es 2B, igual que su desplazamiento a la izquierda conadd %edx,%edx
. Esto probablemente no sea útil; A menos que permita una mayor optimización, ahorrará 3B para elshl $24, %eax
, pero gastará 4Bxor %eax,%eax
al principio ybswap %edx
al final. Zeroing eax te permite usarlocdq
a cero%edx
, por lo que en general es un lavado. Sin embargo, funcionaría mejor: evita que el bloqueo / desaceleración del registro parcial en cada iteración escribaal
y luego leaeax
con shl. : PJalea, 34 bytes
Pruébalo en línea!
fuente
Ruby, 142 bytes
Función anónima; toma una cadena como entrada, devuelve un entero.
fuente
Jalea , 23 bytes
La entrada está en forma de una lista de enteros. Pruébalo en línea! o verificar todos los casos de prueba .
Cómo funciona
Si bien Jelly tiene XOR bit a bit, rellenar la entrada con ceros y alinear el polinomio con el dígito binario más significativo hace que este enfoque, que utiliza listas de bits, sea un poco más corto.
fuente
Pyth, 42 bytes
Banco de pruebas.
fuente
CJam,
3736 bytesPruébalo aquí.
Explicación
fuente
q256bYb_,{(4374732215Ybf*1>.^}*Yb
Guarda algunos bytes.Pyth, 28 bytes
Pruébelo en línea: Demostración o conjunto de pruebas
Explicación:
fuente
JavaScript (ES6), 180 bytes
La falta de un operador XOR de 33 bits, o incluso un operador XOR de 32 bits sin firmar, no es útil.
fuente
CJam, 33 bytes
La entrada está en forma de una cadena. Pruébalo en línea!
Cómo funciona
fuente