MD2 karma dosyamda hangi karakterler daha yaygın?


11

Zor olan basit

Bir dize girdisi verildiğinde, dizeyi MD2 karma algoritmasını kullanarak karma hale getirecek bir komut dosyası yazın ve sonra, sonuçta hangi karakter kümesinin onaltılık dize olarak elde edilen karmada daha yaygın olduğuna bağlı olarak, pozitif bir tamsayı veya negatif tamsayı çıktısı döndürün:

01234567 - (positive)
89abcdef - (negative)
  • Giriş her zaman bir dize olacaktır, ancak 65535'e kadar herhangi bir uzunlukta olabilir
  • Tüm girdi, boşluk ve tümü karma olmalıdır
  • Bu zorluğun amaçları için, 0 tamsayısı ne pozitif ne de negatif olarak kabul edilir (bkz. Kravat çıktısı)
  • Daha yaygın olan küme, karakterlerin 32 karakterlik onaltılık sağlama dizesinde daha yaygın olanıdır
  • Yalnızca boşluk olmayan karakterler geçerli bir doğruluk veya falsey çıktısı olduğu sürece çıktınız herhangi bir türde boşluk içerebilir.
  • Onaltılı dizenin her kümeden tam olarak 16 karakter içerdiği bir kravat olması durumunda, program 0

G / Ç Örnekleri

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

Kazanan Ölçüt

Bu , en az bayt kazanır!


1
MD2 karma algoritmasına, kendi kendine yetme sağlamak için meydan okuma spesifikasyonunda bağlantı vermek veya ideal olarak açıklamak iyi olacaktır.
Martin Ender

@MartinEnder Yapacak!
Skidsdev

Galiba kazanmak , kaybetmek ve bağlamak
math junkie

@mathjunkie true, muhtemelen spec'i çok fazla değiştirmemeliydi, ama sanırım sadece 1, 0 veya -1'e sahip olmak en iyi yoldur
Skidsdev

2
Bu beni bukalemun mücadelesi olarak vuruyor . Dilinizde MD2 yapmak için bir yerleşik veya kitaplık vardır ve geri kalanı basit karakter sayımıdır veya yoktur ve bunu kendiniz uygulamak zorundasınız.
xnor

Yanıtlar:


1

Oktav, 35 bayt

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

* En son Octave sürümünü gerektirir (en az 4.2).

Toplam değer dizisinin histcount'larını, bölmelerinin merkezi 7 ve 8 ile hesaplar, sonra sayımların farkını hesaplar.


Birkaç gün geçtiği için, kazanma cevabını sizinkine koyacağım, eğer biri daha kısa bir çözümle gelirse, her zaman değiştirebilirim. Aferin!
Skidsdev

@Mayube Teşekkürler!
rahnema1

8

Mathematica, 43 bayt

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

Basamak sayısını 01234567eksi cinsinden çıktı olarak verir 89abcdef.


1
Çok kötü, 3E8 ile 9 arasında ve 7 ile 8 arasında değil.
Martin Ender

8

JavaScript (ES6), 731 bayt

Bu canavar MD2 algoritmasını uyguluyor, bu yüzden utanç verici bir şekilde uzun. Dayanarak js-md2 Chen Yi-Cyuan tarafından.

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


Beni döv. Gerçekten güzel bir çaba.
Luke

Şimdiye kadar, yerleşik işlevleri kullanmak yerine tam MD2 algoritmasını uygulayan tek kişi için sahne.
Skidsdev

Daha fazla puanı hak eden en yüksek bayt cevabı.
Sihirli Ahtapot Urn

5

Python 2 + Kripto , 108 99 93 91 87 78 bayt

Python'un MD2 için yerel bir yerleşik yok.

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

@Ovs sayesinde 12 bayt tasarruf edildi.
@FelipeNardiBatista sayesinde 9 bayt tasarruf edildi.


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)bayt sayısını 93
ovs değerine

@ovs Çok zeki!
mbomb007

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

lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-1678 için çıktı sadece sayı değil, herhangi bir sayı olabilir-1,0,1
Felipe Nardi Batista

4

Java 8, 173 bayt

-4 dzaima sayesinde

-128 Oliver sayesinde, bu aslında onun cevabı.

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

Doğruluk için olumlu. Yanlışlık için olumsuz. 0 için 0.


1
Sen içine parantez kaldırarak 4 bayt kaydedebilir forveif
dzaima

1
hex bayt golfed edilebilir: String s="";for(byte b:bytes)h+=h.format("%02x",b);. Ayrıca, tam bir program ama lambda toparlayıcı yazmaya gerek yoktur: a->{... return x;}. Son olarak for döngüsü ile değiştirilebilir int x=s.codePoints().filter(c->c>47&&c<56).count();. Sonuçta, ben golfed senin algoritması için 173 olsun: 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;}. Daha fazla golf oynamak mümkün, ancak bu bayt sayısında net bir gelişme, değil mi?
Olivier Grégoire

Golf için bazı şeyler: println-> printve 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 hakkında çok şey bilmiyorum, aynı zamanda Groovy / Grails'a geçtim.
Sihirli Ahtapot Urn

3

PHP, 50 Bayt

doğruluk için 1, yanlış için -1 ve bir kravat için 0 yazdırır

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

PHP, 58 Bayt

doğruluk için 1, yanlış için -1 ve bir kravat için 0 yazdırır

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

Tüm özellik değişiklikleri için özür dilerim, nihai çıktı gereksinimleri şimdi. Temel olarak şu anda ne var ama tersine (doğruluk için 1, falsey için -1) PHP'de iirc kadar kolay olmalı-0 === 0
Skidsdev

@Mayube bu çok uzun 1 Byte fazla yeterli. En iyi yol, çıktıyı genel değil dilin olanaklarıyla belirtmektir
Jörg Hülsermann

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));ek bayt olmadan hile yapmalıdır.
Christoph

1
Golfçülen versiyon:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Christoph


1

PHP, 56 bayt

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

1

Java 137 130 124 123 bayt

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

Çevrimiçi test edin!

Temel olarak, her bayt için 4. ve 8. en küçük bitlerine karşı kontrol etmemiz istenir. Onaltılık temsilden hiç geçmiyorum. Bu yüzden bitlerle oynamaya başlamak sadece doğal görünüyordu.

Değerler falsey <0, değerler >0doğrudur, değer 0ne doğruluk ne de falsey. Her zamanki doğruluk ve falsey bu kez Java'ya uygulanamaz (çünkü olamaz trueya falseda 0kural ile olamaz if(<truthy>)), bu yüzden beyan etme özgürlüğünü aldım.

kaydeder

  1. 137 -> 130 bayt: bit işlemlerini kullanarak golf oynadım, her seferinde 2 "falsy" biti aldım.
  2. 130 -> 124 bayt: daha fazla bitsel işlem
  3. 124 -> 123 bayt: değiştirilmiştir bytetarafından intdöngü beyanı için de.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.