내 MD2 해시에서 어떤 문자가 더 일반적입니까?


11

도전은 간단하다

문자열 입력이 주어질 때 MD2 해싱 알고리즘을 사용하여 문자열을 해시 한 다음 결과 해시에서 어떤 문자 세트가 16 진 문자열로 더 일반적인 지에 따라 양의 정수 또는 음의 정수 출력을 리턴 하는 스크립트를 작성하십시오 .

01234567 - (positive)
89abcdef - (negative)
  • 입력은 항상 문자열이지만 최대 길이는 65535입니다.
  • 전체 입력, 공백 및 모두를 해시해야합니다.
  • 이 문제를 해결하기 위해 정수 0은 양수도 음수도 아닌 것으로 간주됩니다 (타이 출력 참조).
  • 32 자 16 진 해시 문자열 내에서 문자가 더 일반적인 집합이 더 일반적입니다
  • 공백이 아닌 문자 만 유효한 진실 또는 거짓 출력 인 경우 출력에 모든 종류의 공백이 포함될 수 있습니다.
  • 16 진 문자열이 각 세트에서 정확히 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

나는 승리 , 패배 , 동점
math

@mathjunkie 사실, 아마 사양을 너무 많이 변경해서는 안되지만, 1, 0 또는 -1을 갖는 것이 가장 좋은 방법이라고 생각합니다.
Skidsdev

2
이것은 카멜레온 도전으로 나를 때린다 . 언어에 MD2를 수행 할 수있는 빌트인 또는 라이브러리가 있고 나머지는 간단한 문자 카운팅이거나 그렇지 않으며 직접 구현해야합니다.
xnor

답변:


1

옥타브, 35 바이트

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

* 최신 버전의 Octave (최소 4.2)가 필요합니다.

Bin의 중심이 7과 8 인 해시 문자열의 histcount를 계산 한 다음 counts의 차이를 계산합니다.


며칠이 지났다는 점을 감안할 때 당신의 답을 승리의 답변으로 삼을 것입니다. 누가 누군가가 더 짧은 솔루션을 나중에 만나면 항상 바꿀 수 있습니다. 잘 했어!
Skidsdev

@Mayube 감사합니다!
rahnema1

8

수학, 43 바이트

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

의 자릿수에서 자릿수를 01234567뺀 값을 출력합니다 89abcdef.


1
3E8과 9 사이이고 7과 8 사이가 아닌 너무 나쁩니다 . : |
Martin Ender

8

자바 스크립트 (ES6), 731 바이트

이 괴물은 MD2 알고리즘을 구현하고있어서 너무나 길다. Chen Yi-Cyuan의 js-md2 기반 .

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

파이썬 2 + 암호화 , 108 99 93 91 87 78 바이트

Python에는 MD2 용 기본 제공 기능이 없습니다.

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

@ovs 덕분에 12 바이트를 절약했습니다.
@FelipeNardiBatista 덕분에 9 바이트가 절약되었습니다.


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())-1678의 출력뿐만 아니라 임의의 숫자가 될 수 있습니다-1,0,1
펠리페 나르디 바티스타

4

자바 8, 173 바이트

dzaima 덕분에 -4

-128 Oliver 덕분에 기본적으로 그의 대답입니다.

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
forif
dzaima

1
바이트 16 진수로 골프를 칠 수 있습니다 String s="";for(byte b:bytes)h+=h.format("%02x",b);. 또한 전체 프로그램을 작성할 필요는 없지만 람다로 충분합니다 a->{... return x;}. 마지막으로 for 루프는로 대체 될 수 있습니다 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

골프를 printlnprintfor(char c:s.toCharArray())if("01234567".contains(""+c))x++;for(String c:s.split(""))if("01234567".contains(c))x++;
타는

@ 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, 거짓의 경우 -1)-PHP에서 iirc처럼 상당히 쉬워야합니다-0 === 0
Skidsdev

@Mayube 이것은 너무 길다 1 바이트 더 충분하다. 가장 좋은 방법은 일반적인 언어가 아닌 언어의 가능성으로 출력을 지정하는 것입니다.
Jörg Hülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));추가 바이트없이 트릭을 수행해야합니다.
Christoph

1
골프 버전 :<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph

@Christoph 나는 preg_match_all에 대해 생각하지 못한 바보 같은 느낌
Jörg Hülsermann

1

PHP, 56 바이트

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

1

자바 137 130 124 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 번째 최하위 비트와 비교하여 확인하라는 메시지가 표시됩니다. 나는 16 진수 표현을 전혀 거치지 않습니다. 따라서 비트를 가지고 노는 것이 당연한 것처럼 보였습니다.

가치 <0는 거짓, 가치 >0는 진실, 가치 0는 진실도 거짓도 아니다. (그것이 될 수 없기 때문에 일반적인 truthy 및 falsey 자바이 시간을 적용 할 수 없습니다 true또는 false또는 0규칙에 if(<truthy>)) 내가 같은 선언에 자유를했다, 그래서.

저장

  1. 137-> 130 바이트 : 비트 연산을 사용하여 골프를 치고 "가짜"비트를 얻을 때마다 2를 제거합니다.
  2. 130-> 124 바이트 : 비트 단위 연산
  3. 124-> 123 바이트 : for 루프 선언에서 대체 byte되었습니다 int.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.