Quali caratteri sono più comuni nel mio hash MD2?


11

La sfida è semplice

Scrivere uno script che, quando viene fornito un input di stringa, eseguirà l'hashing della stringa utilizzando l' algoritmo di hashing MD2 , quindi restituirà un numero intero positivo o un output intero negativo in base a quale set di caratteri di seguito è più comune nell'hash risultante come stringa esadecimale:

01234567 - (positive)
89abcdef - (negative)
  • L'input sarà sempre una stringa, ma può avere qualsiasi lunghezza fino a 65535
  • L'intero input, spazi bianchi e tutti, devono essere sottoposti a hash
  • Ai fini di questa sfida, l'intero 0 non è considerato né positivo né negativo (vedere l'output del legame)
  • Il set più comune è quello i cui personaggi sono più comuni nella stringa hash esadecimale di 32 caratteri
  • Il tuo output può contenere spazi bianchi finali di qualsiasi tipo, purché i soli caratteri non bianchi siano un output valido o falso valido
  • In caso di pareggio, in cui la stringa esadecimale contiene esattamente 16 caratteri per ogni set, il programma dovrebbe generare uno 0

Esempi di I / O

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 vincente

Questo è , vince meno byte!


1
Sarebbe utile collegarsi o spiegare idealmente l'algoritmo di hashing MD2 nelle specifiche della sfida per renderlo autonomo.
Martin Ender,

@MartinEnder Lo farà!
Skidsdev,

Penso che sarebbe giusto accettare semplicemente tre valori distinti per vincere , perdere e pareggiare
drogato di matematica

@mathjunkie vero, probabilmente non dovrebbe cambiare così tanto le specifiche, ma immagino che avere solo 1, 0 o -1 sia il modo migliore
Skidsdev

2
Questo mi sembra una sfida camaleontica . O la tua lingua ha un build-in o una libreria per fare MD2 e il resto è un semplice conteggio dei caratteri, oppure no e devi implementarlo da solo.
xnor

Risposte:


1

Ottava, 35 byte

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

* Richiede l'ultima versione di Octave (almeno 4.2).

Calcola gli histco della stringa hash con il suo centro di bin sono 7 e 8, quindi calcola la differenza dei conteggi.


Dato che sono passati alcuni giorni, metterò la tua come risposta vincente, se qualcuno arriva più tardi con una soluzione più breve, posso sempre cambiarla. Molto bene!
Skidsdev,

@Mayube Grazie!
rahnema1,

8

Mathematica, 43 byte

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

Emette il numero di cifre in 01234567meno il numero di cifre in 89abcdef.


1
Peccato che 3Esia tra 8 e 9 e non tra 7 e 8.: |
Martin Ender,

8

JavaScript (ES6), 731 byte

Questo mostro sta implementando l'algoritmo MD2, quindi è imbarazzantemente lungo. Basato su js-md2 di 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'))


Battimi. Uno sforzo davvero bello.
Luca,

I puntelli finora sono gli unici ad implementare effettivamente l'intero algoritmo MD2 anziché utilizzare le funzioni integrate.
Skidsdev,

Risposta in byte più alta che merita più punti.
Magic Octopus Urn

5

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

Python non ha un built-in nativo per MD2.

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

Salvato 12 byte grazie a @ovs.
Salvataggio di 9 byte grazie a @FelipeNardiBatista.


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)dovrebbe ridurre il conteggio dei byte a 93
ovs

@ovs Molto intelligente!
mbomb007,

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

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16per 78. l'output può essere qualsiasi numero, non solo-1,0,1
Felipe Nardi Batista,

4

Java 8, 173 byte

-4 grazie a dzaima

-128 grazie a Oliver, questa è sostanzialmente la sua risposta ora.

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 per la verità. Negativo per falsy. 0 per 0.


1
È possibile salvare 4 byte rimuovendo le parentesi quadre di foreif
dzaima

1
byte in esadecimale può essere golfed: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Inoltre, non è necessario scrivere un programma completo, ma un bastano lambda: a->{... return x;}. Finalmente il ciclo for può essere sostituito da int x=s.codePoints().filter(c->c>47&&c<56).count();. Tutto sommato, ottengo 173 per il vostro 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;}. È possibile giocare a più golf, ma si tratta di un netto miglioramento nel conteggio dei byte, non è vero?
Olivier Grégoire,

Alcune cose da golf: 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 Non so molto di Java 8, sono passato a Groovy / Grails nello stesso periodo.
Magic Octopus Urn

3

PHP, 50 byte

stampa 1 per verità e -1 per falso e 0 per pareggio

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

PHP, 58 byte

stampa 1 per verità e -1 per falso e 0 per pareggio

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

Siamo spiacenti per tutte le modifiche alle specifiche, i requisiti di output finali sono ora disponibili Fondamentalmente quello che hai attualmente ma invertito (1 per la verità, -1 per la falsità) che dovrebbe essere abbastanza facile come Iirc in PHP-0 === 0
Skidsdev

@Mayube questo è troppo lungo 1 byte in più è sufficiente. Il modo migliore è specificare l'output in base alle possibilità della lingua e non in generale
Jörg Hülsermann,

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));dovrebbe fare il trucco senza byte aggiuntivo.
Christoph,

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

@Christoph Mi sento un idiota che non ho pensato a preg_match_all
Jörg Hülsermann

1

PHP, 56 byte

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

1

Java 137 130 124 123 byte

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

Provalo online!

Fondamentalmente, per ogni byte, ci viene chiesto di verificare con il suo quarto e l'ottavo bit meno significativo. Non passo affatto attraverso la rappresentazione esadecimale. Quindi è sembrato naturale iniziare a giocare con i bit.

I valori <0sono falsità, i valori >0sono verità, il valore 0non è né verità né falsità. La solita verità e falsità non possono essere applicate a Java questa volta (perché non può essere trueo falseo 0con la regola if(<truthy>)), quindi mi sono preso la libertà di dichiararlo come tale.

Salva

  1. 137 -> 130 byte: golfato usando operazioni bit, rimuovendo 2 ogni volta che ottengo un bit "falso".
  2. 130 -> 124 byte: più operazioni bit a bit
  3. 124 -> 123 byte: sostituito byteda intnella dichiarazione del ciclo for.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.