在我的MD2哈希中,哪些字符更常见?


11

挑战很简单

编写一个脚本,当给定一个字符串输入时,将使用MD2哈希算法对字符串进行哈希处理,然后返回正整数或负整数输出,基于以下结果在十六进制字符串中最常见的字符集如下:

01234567 - (positive)
89abcdef - (negative)
  • 输入将始终是字符串,但长度最多可为65535
  • 整个输入(空格和全部)必须进行哈希处理
  • 出于此挑战的目的,整数0既不视为正数也不为负数(请参阅平局输出)
  • 在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 '17

我认为这将是公平地简单地接受三个不同值,和领带
数学迷

@mathjunkie是的,可能不应该对规格进行太多更改,但是我猜最好只有1、0或-1
Skidsdev

2
这给我带来变色龙的挑战。您的语言有内置的或可以执行MD2的库,其余的只是简单的字符计数,或者没有,您必须自己实现。
xnor

Answers:


1

八度,35字节

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

*需要最新版本的Octave(至少4.2)。

计算哈希字符串的历史记录,其bin的中心为7和8,然后计算计数之差。


考虑到已经过了几天,我会把您的答案作为最终答案,如果以后有人提出更短的解决方案,我可以随时进行更改。做得好!
Skidsdev '17

@Mayube谢谢!
rahnema17年

8

Mathematica,43个字节

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

输出以的位数01234567减去以的位数89abcdef


1
太糟糕了,3E它介于8和9之间,而不是介于7和8之间。
Martin Ender

8

JavaScript(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 '17

最高字节答案值得更多分。
魔术章鱼缸

5

Python 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'Apr

@ovs非常聪明!
mbomb007 '17

sum(x<'8'for x ......
费利佩·纳尔迪·巴蒂斯塔

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16为78。输出可以是任何数字,而不仅仅是-1,0,1
Felipe Nardi Batista

4

Java 8,173字节

-4感谢dzaima

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

1
十六进制字节可以打高尔夫球:String s="";for(byte b:bytes)h+=h.format("%02x",b);。另外,您不需要编写完整的程序,而只需一个lambda即可: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;}。可以打更多的高尔夫球,但这是字节数的净改进,不是吗?
奥利维尔·格雷戈尔

打高尔夫的一些事情: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我对Java 8不太了解,我大约在同一时间切换到Groovy / Grails。
魔术章鱼缸

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中的-0 === 0
iirc

@Mayube这太长了1个字节就足够了。被指定由语言的可能性,而不是一般的输出的最好方法
约尔格Hülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));应该做到这一点而无需增加字节。
Christoph'Apr

1
高尔夫球版:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph

@Christoph我觉得自己是个白痴,我没有想到preg_match_all
约尔格Hülsermann

1

PHP,56字节

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

1

Java的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位最低有效位。我根本不进行十六进制表示。因此,开始玩小游戏似乎很自然。

价值观<0是虚假的,价值观>0是真实的,价值观0既不是真实的也不是虚假的。这次通常的真假不能应用到Java(因为它不能是trueor false或or0 with the rule if(<truthy>)),所以我可以自由地声明。

节省

  1. 137-> 130字节:使用位操作打高尔夫球,每次得到“假”位都将其删除2。
  2. 130-> 124字节:更多按位运算
  3. 124 - > 123字节:代替byte通过int在for循环声明。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.