อักขระใดที่พบได้บ่อยในแฮช MD2


11

ความท้าทายนั้นง่าย

เขียนสคริปต์ที่เมื่อได้รับอินพุตสตริงจะแฮชสตริงโดยใช้อัลกอริทึมการแปลงค่าMD2แล้วส่งกลับจำนวนเต็มบวกหรือจำนวนเต็มลบที่อิงกับอักขระที่ตั้งไว้ด้านล่างซึ่งพบได้บ่อยในแฮชที่เป็นผลลัพธ์เป็นสตริงเลขฐานสิบหก:

01234567 - (positive)
89abcdef - (negative)
  • อินพุตจะเป็นสตริงเสมอ แต่อาจมีความยาวไม่เกิน 65535
  • ช่องว่างทั้งหมดและช่องว่างทั้งหมดต้องถูกแฮช
  • สำหรับจุดประสงค์ของการท้าทายนี้จำนวนเต็ม 0 จะไม่ถือว่าเป็นค่าบวกหรือค่าลบ (ดูที่เอาต์พุต tie)
  • ชุดที่พบมากขึ้นคือชุดอักขระที่พบได้บ่อยกว่าภายในสตริงแฮชเลขฐานสิบหก 32 อักขระ
  • ผลลัพธ์ของคุณอาจมีช่องว่างต่อท้ายทุกชนิดตราบใดที่อักขระที่ไม่ใช่ช่องว่างเท่านั้นเป็นผลลัพธ์ที่ถูกต้องหรือเป็นเท็จ
  • ในกรณีที่มีการเสมอกันโดยที่สตริงเลขฐานสิบหกมีจำนวน 16 อักขระจากแต่ละชุดโปรแกรมควรส่งออก 0

ตัวอย่าง 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

เกณฑ์การชนะ

นี่คือ , ไบต์ที่น้อยที่สุดชนะ!


1
การเชื่อมโยงหรืออธิบายอัลกอริทึมการแปลงแป้นพิมพ์ MD2 ในสเปคการท้าทายจะเป็นการดีที่จะทำให้มันมีอยู่ในตัวเอง
Martin Ender

@MartinEnder จะทำ!
Skidsdev

ฉันคิดว่ามันจะยุติธรรมก็ยอมรับสามค่าที่แตกต่างกันสำหรับการชนะ , แพ้และผูก
ขี้ยาคณิตศาสตร์

@mathjunkie จริงอาจจะไม่ควรจะมีการเปลี่ยนแปลงข้อมูลจำเพาะมาก แต่ผมคิดว่ามีเพียง 1, 0 หรือ -1 เป็นวิธีที่ดีที่สุด
Skidsdev

2
นัดนี้ฉันเป็นความท้าทายกิ้งก่า ไม่ว่าภาษาของคุณจะมี build-in หรือไลบรารี่ที่จะทำ MD2 และส่วนที่เหลือก็คือการนับตัวอักษรอย่างง่าย ๆ หรือไม่ก็คุณต้องติดตั้งเอง
xnor

คำตอบ:


1

อ็อกเทฟ 35 ไบต์

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

* ต้องการ Octave เวอร์ชันล่าสุด (อย่างน้อย 4.2)

คำนวณฮิสต์เคานต์ของสตริงแฮชกับจุดศูนย์กลางของถังขยะคือ 7 และ 8 จากนั้นคำนวณความแตกต่างของการนับ


เมื่อไม่กี่วันที่ผ่านมาฉันจะวางคำตอบที่ชนะถ้ามีใครเข้ามาทีหลังด้วยวิธีแก้ปัญหาที่สั้นกว่าฉันสามารถเปลี่ยนมันได้ตลอดเวลา ทำได้ดี!
Skidsdev

@Mayube ขอบคุณ!
rahnema1

8

Mathematica ขนาด 43 ไบต์

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

ขาออกจำนวนของตัวเลขในลบด้วยจำนวนตัวเลขใน0123456789abcdef


1
แย่มากที่3Eอยู่ระหว่าง 8 และ 9 และไม่ระหว่าง 7 และ 8: |
Martin Ender

8

JavaScript (ES6), 731 ไบต์

สัตว์ประหลาดตัวนี้กำลังใช้อัลกอริทึม MD2 ดังนั้นมันจึงน่าอาย อ้างอิงจากjs-md2โดย 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'))


เอาชนะฉันไป ความพยายามที่ดีจริงๆ
ลุค

อุปกรณ์ประกอบฉากสำหรับจนถึงขณะนี้เป็นเพียงคนเดียวที่จะใช้จริงอัลกอริทึม MD2 เต็มแทนที่จะใช้ฟังก์ชั่นในตัว
Skidsdev

ไบต์สูงสุดคำตอบสมควรได้รับคะแนนมากขึ้น
Magic Octopus Urn

5

Python 2 + Crypto , 108 99 93 91 87 78 ไบต์

Python ไม่มี builtin ดั้งเดิมสำหรับ MD2

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

บันทึก 12 ไบต์ด้วย @ovs
บันทึกแล้ว 9 ไบต์ขอบคุณ @FelipeNardiBatista


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)ควรลดจำนวนไบต์เป็น 93
ovs

@ovs ฉลาดมาก!
mbomb007

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

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16สำหรับ 78. การส่งออกสามารถเป็นจำนวนเท่าใดก็ได้ไม่ใช่แค่-1,0,1
เฟลิเป้นาร์ดีบาติสตา

4

Java 8, 173 ไบต์

-4 ขอบคุณ dzaima

-128 ขอบคุณโอลิเวอร์นี่เป็นคำตอบของเขาแล้ว

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

คิดบวกเพื่อความจริง เป็นลบสำหรับความเท็จ 0 สำหรับ 0


1
คุณสามารถบันทึก 4 ไบต์โดยการลบวงเล็บปิดforและif
dzaima

1
ไบต์ hex String s="";for(byte b:bytes)h+=h.format("%02x",b);สามารถแข็งแรงเล่นกอล์ฟ: นอกจากนี้คุณไม่จำเป็นต้องเขียนโปรแกรมเต็มรูปแบบ a->{... return x;}แต่พอเพียงแลมบ์ดา: int x=s.codePoints().filter(c->c>47&&c<56).count();สุดท้ายสำหรับวงจะถูกแทนที่ด้วย ทั้งหมดในทุกฉันได้รับ 173 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;}สำหรับขั้นตอนวิธีการของคุณแข็งแรงเล่นกอล์ฟ: การเล่นกอล์ฟเป็นไปได้มากขึ้น แต่นี่เป็นการปรับปรุงสุทธิในจำนวนไบต์ใช่ไหม?
Olivier Grégoire

สิ่งที่ต้องเล่นกอล์ฟ: println-> printและfor(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen

@ OlivierGrégoireฉันไม่รู้อะไรเกี่ยวกับ Java 8 มากนักฉันเปลี่ยนมาใช้ Groovy / Grails ในเวลาเดียวกัน
Magic Octopus Urn

3

PHP, 50 ไบต์

พิมพ์ 1 สำหรับความจริงและ -1 สำหรับเท็จและ 0 สำหรับผูก

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

PHP, 58 ไบต์

พิมพ์ 1 สำหรับความจริงและ -1 สำหรับเท็จและ 0 สำหรับผูก

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

ขออภัยสำหรับการเปลี่ยนแปลงข้อมูลจำเพาะทั้งหมดข้อกำหนดส่งออกขั้นสุดท้ายอยู่ในขณะนี้ โดยทั่วไปสิ่งที่คุณกำลังมี แต่ตรงกันข้าม (1 สำหรับ truthy, -1 สำหรับ falsey) ซึ่งควรจะค่อนข้างง่ายเป็น iirc ใน PHP-0 === 0
Skidsdev

@Mayube นี่ยาวเกินไป 1 Byte ก็เพียงพอแล้ว วิธีที่ดีที่สุดคือการระบุผลลัพธ์โดยความเป็นไปได้ของภาษาและไม่ใช่แบบทั่วไป
JörgHülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));ควรทำเคล็ดลับโดยไม่ต้องไบต์เพิ่มเติม
Christoph

1
รุ่น Golfed:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph

@Christoph ฉันรู้สึกเหมือนคนบ้าที่ฉันไม่ได้คิดเกี่ยวกับ preg_match_all
JörgHülsermann


1

Java 137 130 124 123 123 ไบต์

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

ทดสอบออนไลน์!

โดยทั่วไปสำหรับแต่ละไบต์เราขอให้ตรวจสอบบิตที่สำคัญน้อยที่สุดที่ 4 และ 8 ฉันไม่ผ่านการเป็นตัวแทน hex เลย ดังนั้นจึงเป็นเรื่องธรรมดาที่จะเริ่มเล่นกับบิต

คุณค่า<0คือความเท็จค่านิยม>0คือความจริงคุณค่า0ไม่ใช่ความจริงหรือเท็จ truthy ตามปกติและ falsey ไม่สามารถนำไปใช้ Java เวลานี้ (เพราะมันไม่สามารถtrueหรือfalseหรือ0มีกฎif(<truthy>)) ดังนั้นฉันเอาเสรีภาพในการประกาศดังกล่าว

ประหยัด

  1. 137 -> 130 ไบต์: golfed โดยใช้การดำเนินการบิตลบ 2 ทุกครั้งที่ฉันได้รับบิต "เท็จ"
  2. 130 -> 124 ไบต์: การทำงานระดับบิตเพิ่มเติม
  3. 124 -> 123 ไบต์: แทนที่byteด้วยintในการประกาศลูป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.