Welche Zeichen kommen in meinem MD2-Hash häufiger vor?

11

Die Herausforderung ist einfach

Schreiben Sie ein Skript, das bei Eingabe einer Zeichenfolge die Zeichenfolge mithilfe des MD2-Hashing-Algorithmus hasht und dann entweder eine positive oder eine negative Ganzzahlausgabe zurückgibt, je nachdem, welcher Zeichensatz im resultierenden Hash häufiger als hexadezimale Zeichenfolge verwendet wird:

01234567 - (positive)
89abcdef - (negative)
  • Die Eingabe ist immer eine Zeichenfolge, kann jedoch eine beliebige Länge von bis zu 65535 haben
  • Die gesamte Eingabe, Leerzeichen und alles, muss gehasht werden
  • Für die Zwecke dieser Herausforderung wird die Ganzzahl 0 weder als positiv noch als negativ angesehen (siehe Bindungsausgabe).
  • Der häufigere Satz ist derjenige, dessen Zeichen in der hexadezimalen Hash-Zeichenfolge mit 32 Zeichen häufiger vorkommen
  • Ihre Ausgabe kann nachgestellte Leerzeichen jeglicher Art enthalten, solange die einzigen Nicht-Leerzeichen eine gültige Wahrheits- oder False-Ausgabe sind
  • Bei einem Gleichstand, bei dem die hexadezimale Zeichenfolge genau 16 Zeichen aus jedem Satz enthält, sollte das Programm eine 0 ausgeben

E / A-Beispiele

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

Gewinnkriterium

Das ist , die wenigsten Bytes gewinnen!

Skidsdev
quelle
1
Es wäre gut, den MD2-Hashing-Algorithmus in der Challenge-Spezifikation zu verknüpfen oder idealerweise zu erklären, um ihn in sich geschlossen zu machen.
Martin Ender
@ MartinEnder wird es tun!
Skidsdev
Ich denke , es wäre fair zu einfach drei verschiedene Werte für akzeptieren gewinnen , verlieren , und Krawatte
Mathe -
@mathjunkie wahr, sollte wahrscheinlich nicht so sehr die Spezifikation ändern, aber ich denke, nur 1, 0 oder -1 zu haben ist der beste Weg
Skidsdev
2
Das scheint mir eine Chamäleon-Herausforderung zu sein . Entweder verfügt Ihre Sprache über ein integriertes Programm oder eine Bibliothek für MD2, und der Rest ist das einfache Zählen von Zeichen, oder nicht, und Sie müssen es selbst implementieren.
xnor

Antworten:

1

Oktave, 35 Bytes

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

* Benötigt die neueste Version von Octave (mindestens 4.2).

Berechnet Histcounts der Hash-Zeichenfolge mit der Mitte der Bins sind 7 und 8, berechnet dann die Differenz der Zählungen.

rahnema1
quelle
Angesichts der Tatsache, dass es einige Tage her ist, werde ich Ihre als die beste Antwort nennen. Wenn später jemand eine kürzere Lösung vorlegt, kann ich sie jederzeit ändern. Gut gemacht!
Skidsdev
@ Mayube Danke!
Rahnema1
8

Mathematica, 43 Bytes

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

Gibt die Anzahl der Stellen in 01234567minus der Anzahl der Stellen in aus 89abcdef.

Martin Ender
quelle
1
Schade, dass 3Ezwischen 8 und 9 und nicht zwischen 7 und 8 liegt: |
Martin Ender
8

JavaScript (ES6), 731 Byte

Dieses Monster implementiert den MD2-Algorithmus, es ist also peinlich lang. Basierend auf js-md2 von 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
quelle
Schlage mich dazu. Wirklich schöne Anstrengung.
Luke
Bislang ist dies die einzige Möglichkeit, den vollständigen MD2-Algorithmus zu implementieren, anstatt integrierte Funktionen zu verwenden.
Skidsdev
Höchste Byteantwort, die mehr Punkte verdient.
Magic Octopus Urn
5

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

Python hat kein natives integriertes für MD2.

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

12 Bytes dank @ovs gespeichert.
9 Bytes dank @FelipeNardiBatista gespeichert.

mbomb007
quelle
lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)sollte die Byteanzahl auf 93 reduzieren
ovs
@ovs Sehr klug!
mbomb007
sum(x<'8'for x ......
Felipe Nardi Batista
lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16für 78. Die Ausgabe kann eine beliebige Zahl sein, nicht nur-1,0,1
Felipe Nardi Batista
4

Java 8, 173 Bytes

-4 danke an dzaima

-128 danke an Oliver, das ist jetzt im Grunde seine Antwort.

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;}

Positiv für die Wahrheit. Negativ für Falschheit. 0 für 0.

Magische Krakenurne
quelle
1
Sie können 4 Bytes sparen, indem Sie die umschließenden Klammern von forundif
dzaima
1
Bytes zu hex können golfen werden : String s="";for(byte b:bytes)h+=h.format("%02x",b);. Sie müssen auch kein vollständiges Programm schreiben, aber ein Lambda reicht aus : a->{... return x;}. Schließlich kann die for-Schleife durch ersetzt werden int x=s.codePoints().filter(c->c>47&&c<56).count();. Alles in allem bekomme ich 173 für Ihren Algorithmus, Golf gespielt : 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;}. Mehr Golf ist möglich, aber dies ist eine Nettoverbesserung der Byteanzahl, nicht wahr?
Olivier Grégoire
Einige Dinge zum Golfen: println-> printund for(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen
@ OlivierGrégoire Ich weiß nicht viel über Java 8, ich bin ungefähr zur gleichen Zeit zu Groovy / Grails gewechselt.
Magic Octopus Urn
3

PHP, 50 Bytes

druckt 1 für wahr und -1 für falsch und 0 für ein Unentschieden

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

PHP, 58 Bytes

druckt 1 für wahr und -1 für falsch und 0 für ein Unentschieden

<?=16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));
Jörg Hülsermann
quelle
Wir entschuldigen uns für alle Änderungen an den Spezifikationen. Die endgültigen Ausgabeanforderungen sind jetzt erfüllt. Grundsätzlich, was Sie derzeit haben, aber umgekehrt (1 für wahr, -1 für falsey), was ziemlich einfach sein sollte, wie iirc in PHP-0 === 0
Skidsdev
@ Mayube das ist zu lang 1 Byte mehr ist genug. Der beste Weg ist, die Ausgabe durch die Möglichkeiten der Sprache und nicht allgemein zu spezifizieren
Jörg Hülsermann
1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));sollte den Trick ohne zusätzliches Byte machen.
Christoph
1
Golfversion:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph
@Christoph Ich fühle mich wie ein Idiot, an den ich nicht gedacht habe preg_match_all
Jörg
1

PHP, 56 Bytes

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

Testen Sie es online!

Grundsätzlich werden wir gebeten, für jedes Byte die 4. und 8. niedrigstwertigen Bits zu überprüfen. Ich gehe die Hex-Darstellung überhaupt nicht durch. Es schien also nur natürlich, mit Bits zu spielen.

Werte <0sind falsch, Werte >0sind wahr, Wert 0ist weder wahr noch falsch. Die übliche Wahrheit und Falschheit kann dieses Mal nicht auf Java angewendet werden (weil es nicht trueoder falseoder 0mit der Regel sein kann if(<truthy>)), also habe ich mir die Freiheit genommen, dies als solche zu deklarieren.

Speichert

  1. 137 -> 130 Bytes: Golfen mit Bitoperationen, wobei jedes Mal 2 entfernt werden, wenn ich ein "falsches" Bit erhalte.
  2. 130 -> 124 Bytes: mehr bitweise Operationen
  3. 124 -> 123 Bytes: ersetzt bytedurch intin der for-Schleifendeklaration.
Olivier Grégoire
quelle
1

Tcl + Trf-Paket , 79

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

Probieren Sie es online aus . (Danke @Dennis für das Hinzufügen von Tcl zu TIO.)

Digitales Trauma
quelle