Những ký tự nào phổ biến hơn trong hàm MD2 của tôi?


11

Thử thách rất đơn giản.

Viết một tập lệnh, khi được cung cấp một chuỗi đầu vào, sẽ băm chuỗi bằng thuật toán băm MD2 , và sau đó trả về một đầu ra số nguyên dương hoặc số nguyên âm dựa trên tập ký tự bên dưới phổ biến hơn trong chuỗi băm kết quả dưới dạng chuỗi thập lục phân:

01234567 - (positive)
89abcdef - (negative)
  • Đầu vào sẽ luôn là một chuỗi, nhưng có thể có độ dài bất kỳ lên tới 65535
  • Toàn bộ đầu vào, khoảng trắng và tất cả, phải được băm
  • Đối với mục đích của thử thách này, số nguyên 0 được coi là không dương hoặc âm (xem đầu ra tie)
  • Tập hợp phổ biến hơn là tập hợp các ký tự phổ biến hơn trong chuỗi băm thập lục phân 32 ký tự
  • Đầu ra của bạn có thể chứa khoảng trắng ở bất kỳ loại nào, miễn là các ký tự không phải khoảng trắng là đầu ra hợp lệ hoặc falsey hợp lệ
  • Trong trường hợp hòa, trong đó chuỗi thập lục phân chứa chính xác 16 ký tự từ mỗi bộ, chương trình sẽ xuất ra 0

Ví dụ 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

Tiêu chí chiến thắng

Đây là , ít byte thắng nhất!


1
Sẽ là tốt khi liên kết hoặc giải thích lý tưởng thuật toán băm MD2 trong đặc tả thách thức để làm cho nó khép kín.
Martin Ender

@MartinEnder Sẽ làm được!
Skidsdev

Tôi nghĩ sẽ công bằng khi chỉ cần chấp nhận ba giá trị riêng biệt cho thắng , thuahòa
nghiện toán học

@mathjunkie đúng, có lẽ không nên thay đổi thông số quá nhiều, nhưng tôi đoán chỉ cần có 1, 0 hoặc -1 là cách tốt nhất
Skidsdev

2
Điều này đánh tôi như một thách thức tắc kè hoa . Ngôn ngữ của bạn có tích hợp hoặc thư viện để thực hiện MD2 và phần còn lại là cách đếm ký tự đơn giản hoặc không và bạn phải tự thực hiện.
xnor

Câu trả lời:


1

Octave, 35 byte

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

* Yêu cầu phiên bản mới nhất của Octave (ít nhất là 4.2).

Tính toán số đếm của chuỗi băm với tâm thùng là 7 và 8 sau đó tính toán sự khác biệt của số đếm.


Cho rằng đã được vài ngày tôi sẽ đưa ra câu trả lời chiến thắng, nếu ai đó đến sau với giải pháp ngắn hơn, tôi luôn có thể thay đổi nó. Làm tốt!
Skidsdev

@Mayube Cảm ơn!
rahnema1

8

Toán học, 43 byte

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

Xuất ra số chữ số 01234567trừ đi số chữ số trong 89abcdef.


1
Quá tệ đó 3Elà từ 8 đến 9 chứ không phải từ 7 đến 8 .: |
Martin Ender

8

JavaScript (ES6), 731 byte

Con quái vật này đang thực hiện thuật toán MD2, vì vậy nó rất dài. Dựa trên js-md2 của 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'))


Đánh tôi với nó Nỗ lực thực sự tốt đẹp.
Luke

Đạo cụ cho đến nay, là người duy nhất thực sự thực hiện thuật toán MD2 đầy đủ hơn là sử dụng các hàm dựng sẵn.
Skidsdev

Câu trả lời byte cao nhất xứng đáng được nhiều điểm hơn.
Bạch tuộc ma thuật Urn

5

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

Python không có nội dung dựng sẵn cho MD2.

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

Đã lưu 12 byte nhờ @ovs.
Đã lưu 9 byte nhờ @FelipeNardiBatista.


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)nên giảm số byte xuống còn 93
ovs

@ovs Rất thông minh!
mbomb007

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

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16cho 78. đầu ra có thể là bất kỳ số nào, không chỉ-1,0,1
Felipe Nardi Batista

4

Java 8, 173 byte

-4 cảm ơn dzaima

-128 nhờ Oliver, đây là câu trả lời của anh ấy.

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

Tích cực cho sự thật. Tiêu cực cho giả. 0 cho 0.


1
Bạn có thể lưu 4 byte bằng cách xóa dấu ngoặc kèm theo forif
dzaima

1
byte đến hex có thể được đánh gôn : String s="";for(byte b:bytes)h+=h.format("%02x",b);. Ngoài ra, bạn không cần phải viết một chương trình đầy đủ, nhưng lambda đủ : a->{... return x;}. Cuối cùng, vòng lặp for có thể được thay thế bằng int x=s.codePoints().filter(c->c>47&&c<56).count();. Tất cả trong tất cả, tôi nhận được 173 cho thuật toán của bạn, đánh gôn : 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;}. Có thể chơi gôn nhiều hơn, nhưng đây là một sự cải thiện về số lượng byte, phải không?
Olivier Grégoire

Một số điều cần chơi gôn: println-> printfor(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
Kevin Cruijssen

@ OlivierGrégoire Tôi không biết nhiều về Java 8, tôi đã chuyển sang Groovy / Grails cùng một lúc.
Bạch tuộc ma thuật Urn

3

PHP, 50 byte

in 1 cho trung thực và -1 cho sai và 0 cho cà vạt

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

PHP, 58 byte

in 1 cho trung thực và -1 cho sai và 0 cho cà vạt

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

Xin lỗi cho tất cả các thay đổi thông số kỹ thuật, yêu cầu đầu ra cuối cùng là ngay bây giờ. Về cơ bản những gì bạn hiện có nhưng đã đảo ngược (1 cho sự thật, -1 cho falsey), điều này khá dễ dàng như iirc trong PHP-0 === 0
Skidsdev

@Mayube cái này quá dài 1 Byte nhiều hơn là đủ. Cách tốt nhất là chỉ định đầu ra theo khả năng của ngôn ngữ và không chung chung
Jörg Hülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));nên thực hiện thủ thuật mà không cần thêm byte.
Christoph

1
Phiên bản chơi gôn:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph

@Christoph Tôi cảm thấy như một thằng ngốc mà tôi không nghĩ về preg_match_all
Jörg Hülsermann


1

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

Kiểm tra nó trực tuyến!

Về cơ bản, đối với mỗi byte, chúng tôi được yêu cầu kiểm tra các bit quan trọng thứ 4 và thứ 8 của nó. Tôi không đi qua các đại diện hex cả. Vì vậy, dường như chỉ tự nhiên để bắt đầu chơi với bit.

Giá trị <0là falsey, giá trị >0là sự thật, giá trị 0không phải là sự thật hay falsey. Các truthy thông thường và falsey không thể được áp dụng cho Java thời gian này (vì nó không thể truehay falsehoặc 0với sự cai trị if(<truthy>)), vì vậy tôi mất sự tự do để khai báo như vậy.

Tiết kiệm

  1. 137 -> 130 byte: được chơi bằng cách sử dụng các thao tác bit, loại bỏ 2 lần mỗi khi tôi nhận được bit "giả".
  2. 130 -> 124 byte: hoạt động nhiều bit hơn
  3. 124 -> 123 byte: được thay thế bytebằng inttrong khai báo vòng lặp for.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.