Este concurso acabou.
Devido à natureza dos desafios de policiais e ladrões , o desafio de policiais se torna muito mais fácil quando o interesse no desafio associado a ladrões diminui. Portanto, embora você ainda possa postar funções de hash, sua resposta não será aceita ou fará parte da tabela de classificação.
Este desafio é a busca pelo menor implementação de uma função hash que é resistente ao choque , ou seja, deve ser impraticável encontrar duas mensagens diferentes com o mesmo hash.
Como policial, você tenta inventar e implementar uma função de hash, encontrando o melhor compromisso entre o tamanho do código e a resistência à colisão. Use muitos bytes e outro policial irá derrotar você!
Como ladrão, você tenta frustrar as tentativas dos policiais quebrando suas funções, provando que elas são inadequadas. Isso os forçará a usar mais bytes para fortalecer seus algoritmos!
Desafio da polícia
Tarefa
Implemente uma função hash criptográfica H: I -> O de sua escolha, onde I é o conjunto de todos os números inteiros não negativos abaixo de 2 2 30 e O é o conjunto de todos os números inteiros não negativos abaixo de 2 128 .
Você pode implementar H como uma função real que aceita e retorna um único número inteiro, uma representação de seqüência de caracteres de um número inteiro ou uma matriz de números inteiros ou um programa completo que lê STDIN e imprime em STDOUT na base 10 ou 16.
Pontuação
H que tem que resistir ao desafio dos ladrões definido abaixo.
Se um ladrão derrotar seu envio nas primeiras 168 horas após a publicação, ele será considerado rachado .
A implementação de H deve ser o mais curta possível. A inscrição mais curta e sem rachaduras será a vencedora do desafio da polícia.
Regras adicionais
Se você implementar H como uma função, forneça um wrapper para executar a função a partir de um programa que se comporta conforme explicado acima.
Forneça pelo menos três vetores de teste para o seu programa ou wrapper (entradas de exemplo e suas saídas correspondentes).
H pode ser seu novo design (preferencial) ou um algoritmo conhecido, desde que você o implemente. É proibido usar qualquer tipo de função hash embutida, função de compactação, cifra, PRNG, etc.
Qualquer built-in comumente usado para implementar funções de hash (por exemplo, conversão de base) é um jogo justo.
A saída do seu programa ou função deve ser determinística.
Deve haver um compilador / intérprete gratuito (como na cerveja) que possa ser executado em uma plataforma x86 ou x64 ou de um navegador da web.
Seu programa ou função deve ser razoavelmente eficiente e deve conter qualquer mensagem em I abaixo de 2 2 19 em menos de um segundo.
Para casos extremos, o tempo (de parede) gasto na minha máquina (Intel Core i7-3770, 16 GiB de RAM) será decisivo.
Dada a natureza desse desafio, é proibido alterar o código da sua resposta de qualquer forma, independentemente de alterar ou não a saída.
Se o seu envio foi quebrado (ou mesmo se não), você pode postar uma resposta adicional.
Se sua resposta for inválida (por exemplo, ela não está de acordo com a especificação de E / S), exclua-a.
Exemplo
Python 2.7, 22 bytes
def H(M): return M%17
Embrulho
print H(int(input()))
Desafio de ladrões
Tarefa
Rachar qualquer das bobinas apresentações afixando o seguinte na ladrões rosca : duas mensagens M e N em I de tal modo que H (H) = H (N) e H ≠ N .
Pontuação
Quebrar cada envio de policial ganha um ponto. O ladrão com mais pontos ganha.
No caso de empate, o ladrão empatado que quebrou a finalização mais longa vence.
Regras adicionais
Todo envio de policial só pode ser quebrado uma vez.
Se um envio de policial depende de um comportamento definido ou indefinido da implementação, você precisa encontrar apenas uma falha que funcione (verificável) na sua máquina.
Cada rachadura pertence a uma resposta separada no tópico dos ladrões.
A publicação de uma tentativa de crack inválida o impede de quebrar esse envio específico por 30 minutos.
Você não pode quebrar sua própria submissão.
Exemplo
Python 2.7, 22 bytes por user8675309
1
e
18
Entre os melhores
Envios seguros
Envios sem rachaduras
Você pode usar esse snippet de pilha para obter uma lista de respostas ainda não quebradas.
function g(p){$.getJSON('//api.stackexchange.com/2.2/questions/51068/answers?page='+p+'&pagesize=100&order=desc&sort=creation&site=codegolf&filter=!.Fjs-H6J36w0DtV5A_ZMzR7bRqt1e',function(s){s.items.map(function(a){var h=$('<div/>').html(a.body).children().first().text();if(!/cracked/i.test(h)&&(typeof a.comments=='undefined'||a.comments.filter(function(b){var c=$('<div/>').html(b.body);return /^cracked/i.test(c.text())||c.find('a').filter(function(){return /cracked/i.test($(this).text())}).length>0}).length==0)){var m=/^\s*((?:[^,(\s]|\s+[^-,(\s])+)\s*(?:[,(]|\s-).*?([0-9]+)/.exec(h);$('<tr/>').append($('<td/>').append($('<a/>').text(m?m[1]:h).attr('href',a.link)),$('<td class="score"/>').text(m?m[2]:'?'),$('<td/>').append($('<a/>').text(a.owner.display_name).attr('href',a.owner.link))).appendTo('#listcontent');}});if(s.length==100)g(p+1);});}g(1);
table th, table td {padding: 5px} th {text-align: left} .score {text-align: right} table a {display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><table><tr><th>Language</th><th class="score">Length</th><th>User</th></tr><tbody id="listcontent"></tbody></table>
Respostas:
CJam, 21 bytes
Toma uma sequência de bytes como entrada.
No pseudocódigo:
Exemplos de hashes:
"" (cadeia vazia) -> 1
"Teste" -> 2607833638733409808360080023081587841
"teste" -> 363640467424586895504738713637444713
Pode ser um pouco simples, o intervalo de saída é apenas um pouco mais do que 122 bits, o reforço da iteração tripla já está um pouco quebrado, pois ele faz exatamente a mesma coisa todas as vezes, então insira um hash para 1 no primeiro a iteração será uma pausa completa. Mas é curto, e não há graça em ser muito seguro.
fonte
Python, 109 bytes [ rachado , e novamente ]
Tentei implementar a função única de Jenkins como está, com a única diferença sendo a semente e o número de bits.
Curiosidade: aparentemente, Perl usou o hash dos Jenkins em algum momento .
Embrulho
Exemplos
fonte
C ++, 148 bytes
__uint128_t é uma extensão do GCC e funciona conforme o esperado. O hash é baseado na iteração do hash FNV (eu emprestei o primo, embora
a
sejam os primeiros dígitos do Pi em hexadecimal) com uma rotação do tipo sha1 no início de cada iteração. Compilar com o-O3
hash de um arquivo de 10 MB leva menos de 2 segundos, então ainda há margem para melhorar as iterações no loop interno - mas estou me sentindo generoso hoje.Não uglificado (nomes de variáveis alterados, comentários adicionados, espaço em branco e um par de chaves) para o seu prazer em crack:
Sugestões de golfe são bem-vindas (mesmo que eu não consiga melhorar o código com base nelas).
edit: erros de digitação corrigidos no código não uglificado (a versão em golf permanece inalterada).
fonte
o
parece não inicializado. Ondeoutput
é declarado? Ou talvezo
sejaoutput
?n
. Você realmente verificou o código "desglomerado" para executar?U i=81;i-=3
poderia ter sido ainda mais vil, sem custos significativos de tempo de execução.CJam, 44 bytes [ rachado ]
A entrada está na base 10.
CJam é lento. Espero que seja executado em 1 segundo em algum computador ...
Explicações
Bem, as coisas bidimensionais pareciam ser uma fraqueza ... Pretendia-se fazer alguns cálculos lentos mais rapidamente no início. Mas como ele não pode ser executado em um segundo, não importa o que eu faça, removi o código lento finalmente.
Também deve ser melhor se eu tiver usado bits binários e bases mais altas.
Versão C
fonte
C ++, 182 caracteres (+ cerca de 51 caracteres de padrão)
Boilerplate:
Programa executável com uma função de golfe
fonte
__uint128_t
apenas depois de implementar isso.Pitão, 8 Rachado
Experimente online
Uma resposta meio boba, vou explicar como funciona, porque a maioria das pessoas não consegue ler Pyth. Isso leva o log natural de um mais a entrada e depois o converte em uma string. Essa sequência é revertida e, em seguida, avaliada e convertida em um número inteiro.
Uma tradução em python se pareceria com:
fonte
Python 3, 216 bytes [ rachado ]
Devido a uma incompatibilidade com as especificações, posso pensar em pelo menos uma leve vulnerabilidade, mas, além disso, acho que isso é pelo menos uma prova de força bruta. Eu verifiquei os primeiros 10 milhões de hashes, entre outras coisas.
Em termos de golfe, isso seria mais curto no Python 2, mas sacrifiquei alguns bytes por eficiência (já que provavelmente não vai ganhar de qualquer maneira).
Edit: Esta foi a minha tentativa de implementar o Very Smooth Hash , mas infelizmente 128 bits era muito pequeno.
Embrulho
Exemplos
Explicação do código
Um exemplo do preenchimento para
f(6)
:fonte
C, 87 bytes [ rachado ]
Este é o programa completo; nenhum invólucro necessário. Aceita entrada binária via stdin e gera um hash hexadecimal para stdout.
Isso calcula apenas um hash de 64 bits, então estou apostando um pouco aqui.
Caso alguém esteja se perguntando, as duas constantes
'foo+'
e'bar/'
são os números primos 1718578987 e 1650553391.Exemplos:
Ignora zeros à esquerda:
Entradas de byte único:
Entradas de vários bytes:
fonte
foo|
(d5c9bef71d4f5d1b) efoo\
(d5c9bef71d4f5d1b) produzem hashes MUITO semelhantes.\x00
e\x00\x00
!J - 39 bytes - quebrado
Função pegando uma string como entrada e retornando um número inteiro <2 128 . Suponho que tenhamos que nomear nossa função como válida, portanto, elimine mais 3 caracteres da contagem se pudermos enviar funções anônimas.
Para aqueles que não lêem hieróglifos, aqui está um resumo do que estou fazendo.
a=.(2^128x)&|@^/@
Essa é uma sub-rotina * que pega uma matriz de números e a trata como uma torre de energia, onde a exponenciação é feita no mod 2 128 . Por "torre de energia", quero dizer, se você desse a entrada3 4 5 6
, calcularia3 ^ (4 ^ (5 ^ 6))
.(".p:@+5,9:)a
Essa função pega uma string, converte-a para o número N e calcula os números primos ( n +5) -ésimo ( n +9) -ésimo e, em seguida, lança oa
de antes nele. Ou seja, encontramos op(n+5) ^ p(n+9)
mod 2 128, ondep(k)
está ok
-ésimo primo.H=:_8...\(a...)]
Execute a função acima em sub-blocos de 8 caracteres da entrada e, em seguida,a
todos os resultados juntos e chame a função hash resultanteH
. Eu uso 8 caracteres porque a função "k
-ésimo prime" de J falha quandop(k)
> 2 31 , ou seja,k=105097564
é o maior cofrek
.Tenha algumas saídas de amostra. Você pode tentar isso online no tryj.tk , mas eu realmente recomendo fazer isso em casa baixando o intérprete da Jsoftware .
* Tecnicamente, não é uma função em si mesma, ela se liga a outras funções e atua na saída delas. Mas essa é uma questão semântica de J, não uma diferença conceitual: o fluxo do programa é como eu o descrevi acima.
fonte
Python 3, 118 bytes [ rachado ]
Recuo é uma única guia. Hash simples, ainda não o testei completamente.
Ligue da seguinte maneira:
resultado:
73117705077050518159191803746489514685
fonte
ord(c)
embora, por isso, realmente, qualquer seqüência fará :) (exceto coisas como caracteres nul, eu acho que essas colisões de hash make muito fácil para ficar com uma cadeia de 0-9..)C ++, 239 bytes
Meu primeiro código de golfe! [ Por favor, seja gentil ]
Versão não destruída:
Não é o melhor hash e, definitivamente, não é o código mais curto existente. Aceitando dicas de golfe e esperando melhorar!
Embrulho
Provavelmente não é o melhor do mundo, mas mesmo assim um invólucro
fonte
printf '33333333\x40\xF3\x32\xD6\x56\x91\xCA\x66' | ./hash7_
->a4baea17243177fd
;printf '33333333\x77\x39\xF3\x82\x93\xDE\xA7\x2F' | ./hash7_
->a4baea17243177fd
. O bruteforcer encontra colisões aqui muito mais rapidamente em comparação com outros hash de 64 bits aqui.Java,
299291282 bytes, com falha.Faz algumas operações no BigIntegers e, em seguida, pega o módulo de resultado 2 128 .
fonte
public
você mesmo, economizando 7 caracteres?C, 128 bytes [ rachado ]
Este é mais ou menos o mesmo algoritmo que meu último esforço (quebrado pelo Vi.) , Mas agora tem rodas de hamster suficientes para gerar hashes de 128 bits adequados.
As quatro constantes principais no código são as seguintes:
Como antes, este é um programa completo sem a necessidade de um wrapper. O inteiro I é inserido via stdin como dados binários brutos (big-endian) e o hash O é impresso em hexadecimal para stdout. Zeros à esquerda em I são ignorados.
Exemplos:
fonte
C, 122 bytes [ rachado ]
Loops aninhados, LCGs de meia avaliação e troca variável. O que há para não amar?
Aqui está uma versão ungolf'd para brincar:
Este é um programa totalmente independente que lê de STDIN e imprime em STDOUT.
Exemplo:
Em alguns benchmarks simples, ele processa cerca de 3 MB / s de dados de texto. A velocidade do hash depende dos próprios dados de entrada, portanto, isso provavelmente deve ser levado em consideração.
fonte
PHP 4.1, 66 bytes [ rachado ]
Estou apenas me aquecendo.
Espero que você ache isso interessante.
Eu tentei números tão grandes quanto 999999999999999999999999999.
A saída parecia estar dentro da faixa de 2 128 .
O PHP 4.1 é necessário devido ao
register_globals
diretiva.Ele funciona criando automaticamente variáveis locais da sessão, POST, GET, PEDIDO e cookies.
Ele usa a chave
a
. (EG: acesso porhttp://localhost/file.php?a=<number>
).Se você quiser testá-lo com o PHP 4.2 e mais recente, tente o seguinte:
Esta versão funciona apenas com POST e GET.
Exemplo de saída:
(Garanto que existem números que produzem o mesmo hash).
fonte
C, 134 bytes, Rachado
Este é o programa C completo.
O que faz: A idéia é pegar a entrada como matriz de bytes e anexar bytes pseudo-aleatórios (mas determinísticos) no final para tornar o comprimento igual a 2 2 30 (um pouco mais). A implementação lê entrada byte a byte e começa a usar dados pseudo-aleatórios quando encontra o primeiro caractere que não é um dígito.
Como o PRNG embutido não é permitido, eu o implementei.
Há um comportamento indefinido / definido pela implementação que reduz o código (o valor final não deve ser assinado e eu devo usar tipos diferentes para valores diferentes). E eu não poderia usar valores de 128 bits em C. Versão menos ofuscada:
fonte
Python 2.X - 139 bytes [[ Cracked ]]
Isso é bastante semelhante a todos os outros hashes (LOOP, XOR, SHIFT, ADD) aqui. Venha pegar seus ladrões de pontos;) Eu vou dificultar depois que este for resolvido.
Wrapper (espera um argumento na base 16 também conhecido como hexadecimal):
fonte
H(2**(2**10))
demorou cerca de 8 ou 9 segundos, enquantoH(2**(2**12))
demorou cerca de 29 segundos eH(2**(2**14))
levou mais de dois minutos.Python 2.7 - 161 bytes [[ Cracked ]]
Bem, desde que eu consegui mudar minha primeira função de hash para uma versão inútil antes de publicá-la, acho que publicarei outra versão de uma estrutura semelhante. Desta vez, testei-o contra colisões triviais e testei a maioria das magnitudes de entrada possíveis quanto à velocidade.
Wrapper (não contado no bytecount)
Execute o exemplo (a entrada é sempre um número hexadecimal):
fonte
Ruby, 90 bytes
Um algoritmo de hash altamente aleatório que criei sem olhar para nenhum hash real ... não faço ideia se é bom. é preciso uma string como entrada.
Embrulho:
fonte
comparison of String with 255 failed (ArgumentError)
.gets.to_i
no invólucro.Mathematica, 89 bytes, quebrado
Não é o mais curto.
fonte
PHP, 79 bytes (quebrado. Com um comentário):
Isso faz muitas coisas assustadoras através de conversões de tipo em php, o que dificulta a previsão;) (ou pelo menos espero que sim). Porém, não é a resposta mais curta ou mais ilegível.
Para executá-lo, você pode usar o PHP4 e registrar globais (com? I = 123) ou usar a linha de comando:
fonte
C # - 393 bytes decifrados
Ungolfed:
Eu nunca toquei em criptografia ou hash na minha vida, então seja gentil :)
É uma implementação simples de um FNV-1a hash com alguma matriz girando na entrada. Estou certo de que existe uma maneira melhor de fazer isso, mas é o melhor que posso fazer.
Pode usar um pouco de memória em entradas longas.
fonte
Python 2, 115 bytes [ Rachado já! ]
OK, aqui está o meu último esforço. Apenas 115 bytes porque a nova linha final não é necessária.
Este é um programa completo que insere um número inteiro decimal no stdin e imprime um valor de hash decimal no stdout. Zeros iniciais extras resultarão em diferentes valores de hash, então, assumirei que a entrada não possui nenhum.
Isso funciona preenchendo pedaços de 197 dígitos do número de entrada por meio de uma exponenciação modular. Ao contrário de alguns idiomas, a
int()
função sempre usa como padrão a base 10, portantoint('077')
como 77, não 63.Saídas de amostra:
fonte