Karakter apa yang lebih umum di hash MD2 saya?

11

Tantangannya sederhana

Tulis skrip yang, ketika diberi input string, akan hash string menggunakan algoritma hashing MD2 , dan kemudian mengembalikan bilangan bulat positif atau bilangan bulat negatif berdasarkan pada karakter yang ditetapkan di bawah ini lebih umum dalam hash yang dihasilkan sebagai string heksadesimal:

01234567 - (positive)
89abcdef - (negative)
  • Input akan selalu berupa string, tetapi panjangnya bisa sampai 65535
  • Seluruh input, spasi putih dan semuanya, harus di-hash
  • Untuk keperluan tantangan ini, bilangan bulat 0 tidak dianggap positif atau negatif (lihat hasil seri)
  • Set yang lebih umum adalah karakter yang karakternya lebih umum dalam string hash heksadesimal 32 karakter
  • Output Anda mungkin mengandung spasi spasi apa pun, selama karakter non-spasi tunggal adalah output yang benar atau palsu
  • Jika terjadi ikatan, di mana string heksadesimal mengandung tepat 16 karakter dari setiap set, program harus menghasilkan 0

Contoh 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

Kriteria Kemenangan

Ini adalah , byte terkecil menang!

Skidsdev
sumber
1
Akan lebih baik untuk menautkan atau idealnya menjelaskan algoritma hashing MD2 dalam spesifikasi tantangan untuk membuatnya mandiri.
Martin Ender
@MartinEnder Akan lakukan!
Skidsdev
Saya pikir itu akan adil untuk hanya menerima tiga nilai berbeda untuk menang , kalah , dan mengikat
pecandu matematika
@ mathjunkie benar, mungkin seharusnya tidak mengubah spec begitu banyak, tapi saya kira hanya memiliki 1, 0 atau -1 adalah cara terbaik
Skidsdev
2
Ini menurut saya sebagai tantangan bunglon . Baik bahasa Anda memiliki built-in atau perpustakaan untuk melakukan MD2 dan sisanya adalah penghitungan karakter sederhana, atau tidak dan Anda harus mengimplementasikannya sendiri.
xnor

Jawaban:

1

Oktaf, 35 byte

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

* Membutuhkan Octave versi terbaru (setidaknya 4.2).

Menghitung histcount dari string hash dengan itu pusat sampah adalah 7 dan 8 kemudian menghitung perbedaan jumlah.

rahnema1
sumber
Mengingat sudah beberapa hari saya akan menempatkan jawaban Anda sebagai jawaban yang menang, jika seseorang datang kemudian dengan solusi yang lebih pendek saya selalu dapat mengubahnya. Sudah selesai dilakukan dengan baik!
Skidsdev
@ Mayube Terima kasih!
rahnema1
8

Mathematica, 43 byte

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

Menghasilkan jumlah digit dalam 01234567minus jumlah digit dalam 89abcdef.

Martin Ender
sumber
1
Sayang sekali 3Eantara 8 dan 9 dan bukan antara 7 dan 8.: |
Martin Ender
8

JavaScript (ES6), 731 byte

Monster ini menerapkan algoritma MD2, jadi ini memalukan. Berdasarkan js-md2 oleh 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
sumber
Kalahkan aku untuk itu. Upaya yang sangat bagus.
Luke
Alat peraga untuk, sejauh ini, menjadi satu-satunya yang benar-benar mengimplementasikan algoritma MD2 lengkap daripada menggunakan fungsi bawaan.
Skidsdev
Jawaban byte tertinggi yang pantas mendapatkan lebih banyak poin.
Magic Gurita Guci
5

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

Python tidak memiliki bawaan bawaan untuk MD2.

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

Disimpan 12 byte berkat @ovs.
Disimpan 9 byte berkat @FelipeNardiBatista.

mbomb007
sumber
lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)harus mengurangi jumlah byte menjadi 93
ovs
@ovs Sangat pintar!
mbomb007
sum(x<'8'for x ......
Felipe Nardi Batista
lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16untuk 78. outputnya bisa berapa saja, bukan hanya-1,0,1
Felipe Nardi Batista
4

Java 8, 173 byte

-4 Terima kasih kepada dzaima

Terima kasih kepada Oliver, ini pada dasarnya jawabannya sekarang.

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

Positif untuk kebenaran. Negatif untuk kepalsuan. 0 untuk 0.

Guci Gurita Ajaib
sumber
1
Anda dapat menyimpan 4 byte dengan menghapus tanda kurung fordanif
dzaima
1
byte ke hex dapat golfed: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Juga, Anda tidak perlu menulis program penuh, tapi mencukupi lambda: a->{... return x;}. Akhirnya for loop dapat digantikan oleh int x=s.codePoints().filter(c->c>47&&c<56).count();. Semua dalam semua, saya mendapatkan 173 untuk algoritma Anda, 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;}. Lebih banyak golf mungkin dilakukan, tetapi ini merupakan peningkatan jumlah byte, bukan?
Olivier Grégoire
Beberapa hal untuk bermain golf: println-> printdan for(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen
@ OlivierGrégoire Saya tidak tahu banyak tentang Java 8, saya beralih ke Groovy / Grails sekitar waktu yang sama.
Guci Gurita Ajaib
3

PHP, 50 Bytes

mencetak 1 untuk truey dan -1 untuk false dan 0 untuk tie

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

PHP, 58 Bytes

mencetak 1 untuk truey dan -1 untuk false dan 0 untuk tie

<?=16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));
Jörg Hülsermann
sumber
Maaf untuk semua perubahan spesifikasi, persyaratan hasil akhir sekarang. Pada dasarnya apa yang Anda miliki saat ini tetapi terbalik (1 untuk kebenaran, -1 untuk falsey) yang seharusnya cukup mudah seperti iirc dalam PHP-0 === 0
Skidsdev
@ Mayube ini terlalu panjang 1 Byte lebih dari cukup. Cara terbaik adalah dengan menentukan keluaran berdasarkan kemungkinan bahasa dan bukan umum
Jörg Hülsermann
1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));harus melakukan trik tanpa byte tambahan.
Christoph
1
Versi golf:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph
@Christoph Saya merasa seperti orang idiot yang belum saya pikirkan tentang preg_match_all
Jörg Hülsermann
1

PHP, 56 byte

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

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

Uji secara online!

Pada dasarnya, untuk setiap byte, kami diminta untuk memeriksa bit ke-4 dan ke-8 yang paling signifikan. Saya tidak pergi melalui representasi hex sama sekali. Jadi sepertinya wajar untuk mulai bermain dengan bit.

Nilai <0- nilai itu palsu, nilai >0- nilai itu benar, nilai 0itu juga tidak benar atau salah. Kebenaran dan kepalsuan yang biasa tidak dapat diterapkan ke Jawa saat ini (karena tidak bisa trueatau falseatau0 dengan aturan if(<truthy>)), jadi saya mengambil kebebasan untuk mendeklarasikan seperti itu.

Menghemat

  1. 137 -> 130 byte: golf dengan menggunakan operasi bit, menghapus 2 setiap kali saya mendapatkan bit "falsy".
  2. 130 -> 124 byte: lebih banyak operasi bitwise
  3. 124 -> 123 byte: digantikan byteoleh intdalam deklarasi for loop.
Olivier Grégoire
sumber
1

Paket Tcl + Trf , 79

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

Cobalah online . (Terima kasih @Dennis karena menambahkan Tcl ke TIO.)

Trauma Digital
sumber