Jakie znaki są bardziej powszechne w moim skrócie MD2?

11

Wyzwanie jest proste

Napisz skrypt, który po wprowadzeniu ciągu znaków będzie haszował łańcuch przy użyciu algorytmu mieszającego MD2 , a następnie zwróci wynik liczb całkowitych dodatnich lub ujemnych na podstawie tego, który zestaw znaków poniżej jest bardziej powszechny w wynikowym haszu jako ciąg szesnastkowy:

01234567 - (positive)
89abcdef - (negative)
  • Dane wejściowe zawsze będą ciągiem, ale mogą mieć dowolną długość do 65535
  • Całe wejście, białe znaki i wszystko, musi zostać zaszyfrowane
  • Do celów tego wyzwania liczba całkowita 0 nie jest uważana za ani dodatnią, ani ujemną (patrz wynik remisu)
  • Bardziej powszechnym zestawem jest ten, którego znaki występują częściej w 32-znakowym szesnastkowym łańcuchu mieszającym
  • Dane wyjściowe mogą zawierać dowolne białe znaki końcowe, o ile jedyne znaki niebiałe są prawidłowymi danymi wyjściowymi typu prawda lub falsey
  • W przypadku remisu, w którym ciąg szesnastkowy zawiera dokładnie 16 znaków z każdego zestawu, program powinien wypisać wartość 0

Przykłady we / wy

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

Zwycięskie kryterium

To jest , wygrywa najmniej bajtów!

Skidsdev
źródło
1
Dobrze byłoby połączyć się z algorytmem mieszającym MD2 lub idealnie go wyjaśnić w specyfikacji wyzwania, aby był samodzielny.
Martin Ender
@MartinEnder zrobi!
Skidsdev,
Myślę, że sprawiedliwie byłoby po prostu zaakceptować trzy różne wartości wygranej , przegranej i remisu
ćpun matematyki
@mathjunkie prawda, prawdopodobnie nie powinna tak bardzo zmieniać specyfikacji, ale myślę, że posiadanie 1, 0 lub -1 to najlepszy sposób
Skidsdev
2
Uderza mnie to jako wyzwanie dla kameleona . Albo twój język ma wbudowaną bibliotekę lub bibliotekę MD2, a reszta to proste liczenie znaków, albo nie, i musisz to zaimplementować samodzielnie.
xnor

Odpowiedzi:

1

Oktawa, 35 bajtów

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

* Wymaga najnowszej wersji Octave (co najmniej 4.2).

Oblicza histcounts ciągu hash z jego środkiem przedziałów 7 i 8, a następnie oblicza różnicę zliczeń.

rahnema1
źródło
Biorąc pod uwagę, że minęło kilka dni, podam twoją jako zwycięską odpowiedź, jeśli ktoś przyjdzie później z krótszym rozwiązaniem, zawsze mogę go zmienić. Dobra robota!
Skidsdev,
@Mayube Thanks!
rahnema1
8

Mathematica, 43 bajty

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

Zwraca liczbę cyfr w 01234567minus liczbę cyfr w 89abcdef.

Martin Ender
źródło
1
Szkoda, że 3Ewynosi od 8 do 9, a nie od 7 do 8.: |
Martin Ender
8

JavaScript (ES6), 731 bajtów

Ten potwór implementuje algorytm MD2, więc jest zawstydzająco długi. Na podstawie js-md2 autorstwa 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
źródło
Pokonaj mnie do tego. Naprawdę niezły wysiłek.
Łukasza,
Dotychczasowe rekwizyty jako jedyne faktycznie implementują pełny algorytm MD2 zamiast korzystać z wbudowanych funkcji.
Skidsdev,
Najwyższa bajtowa odpowiedź zasługująca na więcej punktów.
Magic Octopus Urn
5

Python 2 + Crypto , 108 99 93 91 87 78 bajtów

Python nie ma wbudowanego wbudowanego MD2.

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

Zaoszczędź 12 bajtów dzięki @ovs.
Zaoszczędź 9 bajtów dzięki @FelipeNardiBatista.

mbomb007
źródło
lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)powinien zmniejszyć liczbę bajtów do 93
ow
@ovs Bardzo sprytny!
mbomb007,
sum(x<'8'for x ......
Felipe Nardi Batista
lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16dla 78. wyjściem może być dowolna liczba, nie tylko-1,0,1
Felipe Nardi Batista
4

Java 8, 173 bajtów

-4 dzięki dzaima

-128 dzięki Oliverowi, to właściwie jego odpowiedź.

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

Pozytywne dla prawdy. Negatywny dla falsy. 0 dla 0.

Urna Magicznej Ośmiornicy
źródło
1
Możesz zapisać 4 bajty, usuwając nawiasy zamykające foriif
dzaima 19.04.17
1
bajty do hex można golfed: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Ponadto, nie trzeba pisać pełny program, ale wystarczające, lambda: a->{... return x;}. Wreszcie pętla for może zostać zastąpiona przez int x=s.codePoints().filter(c->c>47&&c<56).count();. W sumie, mam 173 dla algorytmu, 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;}. Możliwe jest więcej gry w golfa, ale to poprawa liczby bajtów netto, prawda?
Olivier Grégoire,
Niektóre rzeczy do golfa: println-> printi for(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen
@ OlivierGrégoire Nie wiem wiele o Javie 8, w tym samym czasie przełączyłem się na Groovy / Grails.
Magic Octopus Urn
3

PHP, 50 bajtów

drukuje 1 dla prawdy i -1 dla fałszu i 0 dla remisu

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

PHP, 58 bajtów

drukuje 1 dla prawdy i -1 dla fałszu i 0 dla remisu

<?=16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));
Jörg Hülsermann
źródło
Przepraszamy za wszystkie zmiany specyfikacji, ostateczne wymagania wyjściowe są teraz. Zasadniczo to, co obecnie masz, ale odwróciłeś (1 dla prawdy, -1 dla falsey), co powinno być dość łatwe jak iirc w PHP-0 === 0
Skidsdev
@Mayube, to jest za długie 1 bajt więcej wystarczy. Najlepszym sposobem jest określenie wyniku według możliwości języka, a nie ogólnych
Jörg Hülsermann
1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));powinien zrobić lewę bez dodatkowego bajtu.
Christoph
1
Wersja w golfa:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph
@Christoph Czuję się jak idiota, o którym nie myślę preg_match_all
Jörg Hülsermann
1

PHP, 56 bajtów

while($i<32)${hash(md2,$argn)[$i++]>'7'}++;echo$$_<=>16;
użytkownik63956
źródło
1

Java 137 130 124 123 bajty

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

Przetestuj online!

Zasadniczo, dla każdego bajtu, jesteśmy proszeni o sprawdzenie jego 4 i 8 najmniej znaczących bitów. W ogóle nie przechodzę przez reprezentację szesnastkową. Więc wydawało się naturalne, że gra się bitami.

Wartości <0są falsey, wartości >0są prawdziwe, wartość 0nie jest ani prawdziwa, ani falsey. Zazwyczaj truthy i falsey nie mogą być stosowane do Java tym razem (ponieważ nie może być truelub falselub 0z zasadą if(<truthy>)), więc pozwoliłem sobie zadeklarować jako takie.

Oszczędza

  1. 137 -> 130 bajtów: gra w golfa za pomocą operacji bitowych, usuwając 2 za każdym razem, gdy dostaję „falsy” bit.
  2. 130 -> 124 bajty: więcej operacji bitowych
  3. 124 -> 123 bajty: zastąpione byteprzez intw deklaracji pętli for.
Olivier Grégoire
źródło
1

Pakiet Tcl + Trf , 79

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

Wypróbuj online . (Dzięki @Dennis za dodanie Tcl do TIO.)

Cyfrowa trauma
źródło