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!


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ń.


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.


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'))


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.


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.


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

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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.