MD2ハッシュではどの文字がより一般的ですか?


11

挑戦は簡単です

文字列入力が与えられると、MD2ハッシュアルゴリズムを使用して文字列をハッシュするスクリプトを記述し、結果のハッシュで16進数文字列としてより一般的な文字セットに基づいて正の整数または負の整数出力を返します。

01234567 - (positive)
89abcdef - (negative)
  • 入力は常に文字列になりますが、65535までの任意の長さにすることができます
  • 入力全体、空白およびすべてをハッシュする必要があります
  • このチャレンジのために、整数0は正でも負でもないと見なされます(tie出力を参照)
  • より一般的なセットは、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ハッシュアルゴリズムにリンクするか、理想的に説明して、自己完結型にすることをお勧めします。
マーティンエンダー

@MartinEnderします!
Skidsdev

winlose、およびtieの
数学ジャンキー

@mathjunkie true、おそらく仕様をそれほど変更するべきではありませんが、1、0、または-1を持つことが最善の方法だと思います
-Skidsdev

2
これはカメレオンの挑戦として私を打つ。お使いの言語にはMD2を実行するためのビルドインまたはライブラリがあり、残りは単純な文字カウントです。そうでない場合は、自分で実装する必要があります。
XNOR

回答:


1

オクターブ、35バイト

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

* Octaveの最新バージョン(少なくとも4.2)が必要です。

ビンの中心が7と8であるハッシュ文字列のhistcountsを計算してから、カウントの差を計算します。


数日が過ぎたので、私はあなたのものを勝利の答えとしてあげます。誰かが後でより短い解決策を見つけたら、いつでも変更できます。よくやった!
Skidsdev

@Mayubeありがとう!
rahnema1


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

より多くのポイントに値する最高のバイト回答。
魔法のタコUr

5

Python 2 + Crypto108 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 ......
フェリペナルディバティスタ

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-1678の場合、出力は単なる数字ではなく、任意の数にすることができます-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
forand の囲み括弧を削除することで4バイトを節約できますif
-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;}。より多くのゴ​​ルフが可能ですが、これはバイト数の正味の改善ですよね?
オリヴィエグレゴワール

ゴルフに関するいくつかのこと:println-> printおよびfor(char c:s.toCharArray())if("01234567".contains(""+c))x++;->for(String c:s.split(""))if("01234567".contains(c))x++;
ケビンクルーッセン

@OlivierGrégoireJava 8についてあまり知りませんが、同じ頃にGroovy / Grailsに切り替えました。
魔法のタコUr

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バイト以上あれば十分です。一般的な言語の可能性により、出力を指定していないことです最良の方法
イェルクHülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));追加のバイトなしでトリックを行う必要があります。
クリストフ

1
ゴルフ版:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
クリストフ

私はpreg_match_allについて考えていないことを馬鹿のような@Christoph I感触
ヨルグ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は(それができないため、Javaのこの時間を適用することはできませんtrueか、falseまたは0ルールif(<truthy>))ので、私は、次のような宣言に自由を取りました。

保存します

  1. 137-> 130バイト:ビット演算を使用してゴルフし、「偽の」ビットを取得するたびに2を削除します。
  2. 130-> 124バイト:よりビット単位の操作
  3. 124 - > 123バイト:置き換えるbyteことによってintループの宣言で。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.