Quais caracteres são mais comuns no meu hash MD2?


11

O desafio é simples

Escreva um script que, quando recebida uma entrada de string, faça o hash da string usando o algoritmo de hash MD2 e, em seguida, retorne um número inteiro positivo ou um resultado inteiro negativo com base no qual conjunto de caracteres abaixo é mais comum no hash resultante como uma string hexadecimal:

01234567 - (positive)
89abcdef - (negative)
  • A entrada sempre será uma sequência, mas pode ter qualquer comprimento até 65535
  • Toda a entrada, espaço em branco e tudo, deve ser hash
  • Para os propósitos deste desafio, o número inteiro 0 não é considerado positivo nem negativo (consulte a saída do empate)
  • O conjunto mais comum é aquele cujos caracteres são mais comuns na cadeia de hash hexadecimal de 32 caracteres
  • Sua saída pode conter espaços em branco à direita de qualquer tipo, desde que os únicos caracteres que não sejam espaços em branco sejam uma saída válida ou falsa
  • No caso de um empate, onde a cadeia hexadecimal contém exatamente 16 caracteres de cada conjunto, o programa deve emitir um 0

Exemplos de E / S

Input: "" (Empty String)
Hash: 8350e5a3e24c153df2275c9f80692773
Output: 1

Input: "The quick brown fox jumps over the lazy cog" (Without quotes)
Hash: 6b890c9292668cdbbfda00a4ebf31f05
Output: -1

Input: "m" (Without quotes)
Hash: f720d455eab8b92f03ddc7868a934417
Output: 0

Critério vencedor

Isso é , o menor número de bytes vence!


1
Seria bom vincular ou explicar idealmente o algoritmo de hash MD2 na especificação de desafio para torná-lo independente.
Martin Ender

@MartinEnder Will do!
precisa saber é o seguinte

Eu acho que seria justo para simplesmente aceitar três valores distintos para vitória , perder , e laço
viciado em matemática

@mathjunkie verdade, provavelmente não deveria estar mudando a especificação tanto, mas acho que ter apenas 1, 0 ou -1 é a melhor maneira
Skidsdev

2
Isso me parece um desafio de camaleão . Seu idioma possui um build-in ou biblioteca para executar o MD2 e o restante é uma contagem simples de caracteres, ou não, e você precisa implementá-lo.
Xnor

Respostas:


1

Oitava, 35 bytes

@(s)diff(hist(hash('md2',s),+'78'))

* Requer a versão mais recente do Octave (pelo menos 4.2).

Calcula que as contas históricas da cadeia de hash com seu centro de posições são 7 e 8 e depois calcula a diferença de contagens.


Dado que já faz alguns dias, colocarei a sua como a resposta vencedora, se alguém aparecer mais tarde com uma solução mais curta, sempre posso alterá-la. Bem feito!
Skidsdev 21/04

@Mayube Thanks!
precisa saber é o seguinte

8

Mathematica, 43 bytes

Tr@Sign[15-2#~Hash~"MD2"~IntegerDigits~16]&

Emite o número de dígitos em 01234567menos o número de dígitos em 89abcdef.


1
Pena que 3Eestá entre 8 e 9 e não entre 7 e 8.: |
Martin Ender

8

JavaScript (ES6), 731 bytes

Esse monstro está implementando o algoritmo MD2, por isso é embaraçosamente longo. Baseado em js-md2 por Chen Yi-Cyuan.

let f =

m=>{L=x=s=b=0,n=m.length,M=[],X=[],C=[],S=[...atob`KS5DyaLYfAE9NlSh7PAGE2KnBfPAx3OMmJMr2bxMgsoem1c8/dTgFmdCbxiKF+USvk7E1tqe3kmg+/WOuy/ueqloeZEVsgc/lMIQiQsiXyGAf12aWpAyJzU+zOe/95cD/xkws0iltdHXXpIqrFaqxk+4ONKWpH22dvxr4px0BPFFnXBZZHGHIIZbz2XmLagCG2Alra6wufYcRmFpNEB+D1VHoyPdUa86w1z5zrrF6iYsUw1uhSiECdPfzfRBgU1Satw3yGzBq/ok4XsIDL2xSniIlYvjY+ht6cvV/jsAHTny77cOZljQ5KZ3cvjrdUsKMURQtI/tHxrbmY0znxGDFA`].map(c=>c[O='charCodeAt']());for(l=1;l-2;){for(j=19;j--;)M[j]=M[16+j]||0;for(i=s;i<16;x++)L=(x-n||(b+=i-s,s=i-16,l=2),C[i]^=S[(M[i++]=x<n?m[O](x):16-(b&15))^L]);for(i=0;i<l;i++){for(j=16;j--;)X[32+j]=(X[16+j]=(i?C:M)[j])^X[j];for(t=j=0;j<18;t=t+j++&255)for(k=0;k<48;)t=X[k++]^=S[t]}}for(i=16,n=-i;i--;)n+=!(X[i]&8)+!(X[i]&128);return n}

console.log(f(''))
console.log(f('The quick brown fox jumps over the lazy cog'))
console.log(f('m'))


Bata-me para isso. Esforço realmente bom.
Luke

Props por, até agora, ser o único a realmente implementar o algoritmo MD2 completo, em vez de usar funções internas.
precisa saber é o seguinte

Resposta de bytes mais altos que merece mais pontos.
Magic Octopus Urn

5

Python 2 + Crypto , 108 99 93 91 87 78 bytes

O Python não possui um built-in nativo para o MD2.

from Crypto.Hash import*
lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16

Economizou 12 bytes graças a @ovs.
Guardado 9 bytes graças a @FelipeNardiBatista.


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)deve reduzir a contagem de bytes para 93
ovs 19/04/19

@ovs Muito esperto!
mbomb007

sum(x<'8'for x ......
Felipe Nardi Batista

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16para 78. A saída pode ser qualquer número, não apenas-1,0,1
Felipe Nardi Batista

4

Java 8, 173 bytes

-4 graças a dzaima

Graças a Oliver, esta é basicamente a resposta dele agora.

a->{String h="";for(byte b:java.security.MessageDigest.getInstance("MD2").digest(a.ge‌​tBytes()))h+=h.forma‌​t("%02x",b);return h.codePoints().filter(c->c>47&&c<56).count()-16;}

Positivo para a verdade. Negativo por falsidade. 0 para 0.


1
Você pode salvar 4 bytes, removendo os colchetes encerram de foreif
dzaima

1
bytes para hex pode ser golfed: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Além disso, você não precisa escrever um programa completo, mas um bastam lambda: a->{... return x;}. Finalmente, o loop for pode ser substituído por int x=s.codePoints().filter(c->c>47&&c<56).count();. Ao todo, eu recebo 173 para o seu algoritmo, golfed: a->{String h="";for(byte b:java.security.MessageDigest.getInstance("MD2").digest(a.getBytes()))h+=h.format("%02x",b);return h.codePoints().filter(c->c>47&&c<56).count()-16;}. É possível mais golfe, mas isso é uma melhoria líquida na contagem de bytes, não é?
Olivier Grégoire

Algumas coisas para o golfe: println-> printe for(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen

@ OlivierGrégoire Não sei muito sobre o Java 8, mudei para o Groovy / Grails na mesma época.
Magic Octopus Urn

3

PHP, 50 bytes

imprime 1 para truthy e -1 para false e 0 para empate

<?=preg_match_all("#[0-7]#",hash(md2,$argn))<=>16;

PHP, 58 bytes

imprime 1 para truthy e -1 para false e 0 para empate

<?=16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));

Desculpe por todas as alterações nas especificações, os requisitos finais de saída já estão disponíveis. Basicamente o que você tem atualmente, mas invertida (1 para truthy, -1 para Falsey), que deve ser bastante fácil como IIRC em PHP-0 === 0
Skidsdev

@ Mayube isso é muito longo 1 Byte a mais é suficiente. A melhor maneira é especificar a saída pelas possibilidades da linguagem e não geral
Jörg Hülsermann 19/04

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));deve executar o truque sem byte adicional.
Christoph

1
Versão golfed:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph

@ Christoph Eu me sinto como um idiota que eu não penso sobre preg_match_all
Jörg Hülsermann

1

PHP, 56 bytes

while($i<32)${hash(md2,$argn)[$i++]>'7'}++;echo$$_<=>16;

1

Java 137 130 124 123 bytes

a->{int c=32;for(int b:java.security.MessageDigest.getInstance("MD2").digest(a.getBytes()))c-=(b>>6&2)+(b>>2&2);return c;}

Teste online!

Basicamente, para cada byte, somos solicitados a verificar seus 4 e 8 bits menos significativos. Eu não passo pela representação hexadecimal. Por isso, parecia natural começar a brincar com bits.

Valores <0são falsey, valores >0são verdadeiros, valor 0não é verdade ou falsey. A verdade e a falsa de sempre não podem ser aplicadas ao Java desta vez (porque não pode ser trueou falseou 0com a regra if(<truthy>)), então tomei a liberdade de declarar como tal.

Economizar

  1. 137 -> 130 bytes: joguei golfe usando operações de bit, removendo 2 toda vez que recebo um bit "falso".
  2. 130 -> 124 bytes: mais operações bit a bit
  3. 124 -> 123 bytes: substituído bytepor intna declaração do loop for.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.