¿Qué caracteres son más comunes en mi hash MD2?

11

El desafío es simple.

Escriba una secuencia de comandos que, cuando se le dé una entrada de cadena, haga un hash de la cadena utilizando el algoritmo de hash MD2 , y luego devuelva un entero positivo o una salida de entero negativo según el conjunto de caracteres que se muestra a continuación en el hash resultante como una cadena hexadecimal:

01234567 - (positive)
89abcdef - (negative)
  • La entrada siempre será una cadena, pero puede tener cualquier longitud hasta 65535
  • Toda la entrada, el espacio en blanco y todo, debe ser hash
  • Para los propósitos de este desafío, el entero 0 no se considera positivo ni negativo (ver salida de empate)
  • El conjunto más común es aquel cuyos caracteres son más comunes dentro de la cadena hash hexadecimal de 32 caracteres
  • Su salida puede contener espacios en blanco finales de cualquier tipo, siempre que los únicos caracteres que no sean espacios en blanco sean una salida verdadera o falsey válida
  • En caso de empate, donde la cadena hexadecimal contiene exactamente 16 caracteres de cada conjunto, el programa debería generar un 0

Ejemplos 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

Criterio ganador

Este es el , ¡gana la menor cantidad de bytes!

Skidsdev
fuente
1
Sería bueno vincular o idealmente explicar el algoritmo de hash MD2 en la especificación de desafío para hacerlo autónomo.
Martin Ender
@MartinEnder lo hará!
Skidsdev
Creo que sería justo simplemente aceptar tres valores distintos para ganar , perder y empatar
adicto a las matemáticas
@mathjunkie es cierto, probablemente no debería cambiar tanto la especificación, pero supongo que solo tener 1, 0 o -1 es la mejor manera
Skidsdev
2
Esto me parece un desafío de camaleón . O su idioma tiene una biblioteca o una función incorporada para hacer MD2 y el resto es un simple recuento de caracteres, o no lo tiene y debe implementarlo usted mismo.
xnor

Respuestas:

1

Octava, 35 bytes

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

* Requiere la última versión de Octave (al menos 4.2).

Calcula los conteos históricos de la cadena hash con su centro de ubicaciones son 7 y 8 y luego calcula la diferencia de conteos.

rahnema1
fuente
Dado que han pasado unos días, presentaré la suya como la respuesta ganadora, si alguien llega más tarde con una solución más corta, siempre puedo cambiarla. ¡Bien hecho!
Skidsdev
@Mayube ¡Gracias!
rahnema1
8

Mathematica, 43 bytes

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

Emite el número de dígitos en 01234567menos el número de dígitos en 89abcdef.

Martin Ender
fuente
1
Lástima que 3Eesté entre 8 y 9 y no entre 7 y 8.: |
Martin Ender
8

JavaScript (ES6), 731 bytes

Este monstruo está implementando el algoritmo MD2, por lo que es vergonzosamente largo. Basado en 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'))

Arnauld
fuente
Gáname a eso. Muy buen esfuerzo.
Lucas
Apoyos para, hasta ahora, ser el único en implementar realmente el algoritmo MD2 completo en lugar de utilizar funciones integradas.
Skidsdev
La respuesta del byte más alto merece más puntos.
Urna mágica de pulpo
5

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

Python no tiene un nativo incorporado para MD2.

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

Guardado 12 bytes gracias a @ovs.
Guardado 9 bytes gracias a @FelipeNardiBatista.

mbomb007
fuente
lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)debería reducir el recuento de bytes a 93
ovs
@ovs Muy inteligente!
mbomb007
sum(x<'8'for x ......
Felipe Nardi Batista
lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16para 78. la salida puede ser cualquier número, no solo-1,0,1
Felipe Nardi Batista
4

Java 8, 173 bytes

-4 gracias a dzaima

-128 gracias a Oliver, esta es básicamente su respuesta ahora.

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 la verdad. Negativo para la falsedad. 0 por 0.

Urna de pulpo mágico
fuente
1
Puede guardar 4 bytes eliminando los corchetes de foryif
dzaima
1
bytes en hexadecimal se puede golfed: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Además, no es necesario escribir un programa completo, pero basta una lambda: a->{... return x;}. Finalmente, el bucle for puede ser reemplazado por int x=s.codePoints().filter(c->c>47&&c<56).count();. Con todo, me sale 173 para su 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;}. Es posible jugar más al golf, pero esta es una mejora neta en el conteo de bytes, ¿no es así?
Olivier Grégoire
Algunas cosas para jugar al golf: println-> printy for(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen
@ OlivierGrégoire No sé mucho sobre Java 8, me cambié a Groovy / Grails al mismo tiempo.
Urna mágica del pulpo
3

PHP, 50 bytes

imprime 1 para verdad y -1 para falso y 0 para un empate

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

PHP, 58 bytes

imprime 1 para verdad y -1 para falso y 0 para un empate

<?=16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));
Jörg Hülsermann
fuente
Lo sentimos por todos los cambios de especificaciones, los requisitos de salida final están ahora. Básicamente lo que tiene actualmente pero revertido (1 para veracidad, -1 para falsey), que debería ser bastante fácil como iirc en PHP-0 === 0
Skidsdev
@Mayube esto es demasiado largo 1 byte más es suficiente. La mejor manera es especificar la salida por las posibilidades del lenguaje y no en general
Jörg Hülsermann
1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));debería hacer el truco sin byte adicional.
Christoph
1
Golfed versión:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph
@ Christoph Me siento como un idiota en el que no he pensado preg_match_all
Jörg Hülsermann
1

PHP, 56 bytes

while($i<32)${hash(md2,$argn)[$i++]>'7'}++;echo$$_<=>16;
usuario63956
fuente
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;}

¡Pruébalo en línea!

Básicamente, para cada byte, se nos pide que verifiquemos sus bits 4 y 8 menos significativos. No paso por la representación hexadecimal en absoluto. Entonces parecía natural comenzar a jugar con bits.

Los valores <0son falsey, los valores >0son verdaderos, el valor 0no es ni verdadero ni falsey. El Truthy y Falsey- habitual no se pueden aplicar a Java este tiempo (ya que no puede ser trueni falseo 0con la regla if(<truthy>)), así que me tomé la libertad de declarar como tal.

Ahorra

  1. 137 -> 130 bytes: golf usando operaciones de bit, eliminando 2 cada vez que obtengo un bit "falso".
  2. 130 -> 124 bytes: más operaciones bit a bit
  3. 124 -> 123 bytes: reemplazado bytepor inten la declaración de bucle for.
Olivier Grégoire
fuente
1

Paquete Tcl + Trf , 79

package require Trf
puts [expr [regexp -all \[0-7\] [hex -m e [md2 $argv]]]-16]

Pruébalo en línea . (Gracias @Dennis por agregar Tcl a TIO).

Trauma digital
fuente