Créditos
Esse desafio teve origem em @miles .
Crie uma função que calcule o hash CRC32 de uma sequência de entrada. A entrada será uma sequência ASCII de qualquer tamanho. A saída será o hash CRC32 dessa sequência de entrada.
Explicação
O algoritmo do CRC32 e outro CRC é essencialmente o mesmo, portanto apenas o CRC3 será demonstrado aqui.
Primeiramente, você tem o polinômio do gerador, que na verdade é um número inteiro de 4 bits [n + 1] (seria de 33 bits no CRC32).
Neste exemplo, o polinômio do gerador é 1101
.
Então, você terá a string a ser hash, o que neste exemplo seria 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^
O restante obtido em (21)
, quando a região 1 é zero, ou seja 001
, seria o resultado do hash CRC3.
Especificações
- O polinômio do gerador é
0x104C11DB7
, ou0b100000100110000010001110110110111
, ou4374732215
. - A entrada pode ser uma sequência de caracteres ou uma lista de números inteiros ou qualquer outro formato razoável.
- A saída deve ser uma sequência hexadecimal ou apenas um número inteiro ou qualquer outro formato razoável.
- Built-ins que calculam o hash CRC32 não são permitidos.
Objetivo
Aplicam -se regras padrão para o código-golfe .
O código mais curto vence.
Casos de teste
input output (hex)
"code-golf" 147743960 08CE64D8
"jelly" 1699969158 65537886
"" 0 00000000
Respostas:
Intel x86,
34302927 bytesPega o endereço da sequência terminada em zero no ESI e retorna o CRC no EBX:
Desmontagem (sintaxe da AT&T):
Incorporando sugestões de Peter Cordes para economizar mais quatro bytes. Isso pressupõe uma convenção de chamada em que o sinalizador de direção para instruções de string é limpo na entrada.
Incorporando a sugestão de Peter Ferrie para usar push literal e pop para carregar uma constante, economizando um byte.
Incorporando a sugestão de Peter Ferrie para pular para o segundo byte de uma
xorl %eax, %ebx
instrução que é umaretl
instrução, combinada com a alteração da interface da rotina para obter uma string terminada em zero em vez de comprimento, economizando dois bytes no total.fonte
cld
insn (como fiz na minha resposta do adler32 ). É prática normal permitir convenções de chamada totalmente arbitrárias para respostas asm?edi
e apontar o ponteiroesi
(talvez não seja estendido a zero, então talvez estrague tudo e exija um Ponteiro zero estendido de 64 bits). (x32 para que você possa usar com segurança de 32 bits matemática ponteiro, mas ainda tem os Registre-args chamando convenção Desde que você não use.inc
, não há nenhuma desvantagem para o modo de comprimento.)edx
ordem invertida?bswap edx
é apenas 2B.shr %edx
é 2B, igual ao seu turno esquerdoadd %edx,%edx
. Provavelmente isso não é útil; A menos que ele permita mais otimização, você economiza 3B para oshl $24, %eax
, mas gasta 4Bxor %eax,%eax
no início ebswap %edx
no final. Zerar o eax permite que você usecdq
para zerar%edx
; portanto, no geral, é uma lavagem. Porém, o desempenho seria melhor: evita a paralisação / desaceleração parcial do registro em cada iteração, da escritaal
e da leituraeax
com shl. : PGeléia, 34 bytes
Experimente online!
fonte
Ruby, 142 bytes
Função anônima; pega uma string como entrada, retorna um número inteiro.
fonte
Gelatina , 23 bytes
A entrada está na forma de uma lista de números inteiros. Experimente online! ou verifique todos os casos de teste .
Como funciona
Enquanto o Jelly possui XOR bit a bit, preencher a entrada com zeros e alinhar o polinômio com o dígito binário mais significativo faz com que essa abordagem, que utiliza listas de bits, seja um pouco menor.
fonte
Pitão, 42 bytes
Suíte de teste.
fonte
CJam,
3736 bytesTeste aqui.
Explicação
fonte
q256bYb_,{(4374732215Ybf*1>.^}*Yb
salva alguns bytes.Pitão, 28 bytes
Experimente on-line: Demonstration or Test Suite
Explicação:
fonte
JavaScript (ES6), 180 bytes
A falta de um operador XOR de 33 bits, ou mesmo de um operador XOR de 32 bits não assinado, é inútil.
fonte
CJam, 33 bytes
A entrada está no formato de uma sequência. Experimente online!
Como funciona
fonte