Які символи частіше зустрічаються в моєму хеші MD2?


11

Завдання проста

Напишіть сценарій, який при введенні рядка буде хешувати рядок за допомогою алгоритму хешування MD2 , а потім поверне або позитивне ціле, або негативне ціле число, на основі якого набір символів нижче є більш поширеним у отриманому хеші як шістнадцятковий рядок:

01234567 - (positive)
89abcdef - (negative)
  • Вхід завжди буде рядком, але може бути будь-якої довжини до 65535
  • Весь вхід, пробіл і всі повинні бути хешовані
  • Для цілей цього виклику ціле число 0 не вважається ні позитивним, ні негативним (див. Результат зв'язання)
  • Більш поширеним набором є той, хто символи частіше зустрічаються в шістнадцятковій хеш-рядку 32 символів
  • Ваш вихід може містити будь-який пробіл будь-якого типу, якщо єдині символи, що не містять пробілів, є дійсним виводом або фальсиєю
  • У разі прив'язки, де шістнадцятковий рядок містить рівно 16 символів з кожного набору, програма повинна вивести 0

Приклади вводу / виводу

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

Я думаю, було б справедливо просто прийняти три чіткі значення для перемоги , програшу та зв'язати матч
математика наркоман

@mathjunkie правда, напевно, не слід так сильно змінювати специфікацію, але, мабуть, найкращий спосіб мати 1, 0 або -1
Skidsdev

2
Це сприймає мене як виклик хамелеона . Або у вашій мові є вбудована або бібліотека для виконання MD2, а решта - це простий підрахунок символів, або це не так, і вам доведеться реалізувати це самостійно.
xnor

Відповіді:


1

Октава, 35 байт

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

* Потрібна остання версія Octave (принаймні 4.2).

Обчислює кількість рахунків хеш-рядка з центром бункерів 7 і 8, а потім обчислює різницю підрахунків.


Враховуючи, що минуло кілька днів, я виберу вашу як виграшну відповідь, якщо хтось піде пізніше зі скороченим рішенням, я завжди можу це змінити. Молодці!
Skidsdev

@Mayube Дякую!
rahnema1

8

Математика, 43 байти

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

Виводить кількість цифр 01234567мінус кількість цифр у 89abcdef.


1
Шкода, що 3Eце між 8 і 9, а не між 7 і 8.: |
Мартін Ендер

8

JavaScript (ES6), 731 байт

Цей монстр реалізує алгоритм MD2, тож він незручно довгий. На основі js-md2 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'))


Бий мене до цього. Дійсно приємні зусилля.
Лука

Наразі реквізит є єдиним, хто реально реалізує повний алгоритм MD2, а не використовує вбудовані функції.
Скидсдев

Найвищий байт відповідь заслуговує більше балів.
Чарівний восьминіг Урна

5

Python 2 + Crypto , 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

Збережено 12 байт завдяки @ovs.
Збережено 9 байт завдяки @FelipeNardiBatista.


lambda s:cmp(sum((int(x,16)<8)-.5for x in MD2.new(s).hexdigest()),0)має зменшити кількість байтів до 93
о.

@ovs Дуже розумний!
mbomb007


lambda s:sum(x<'8'for x in MD2.new(s).hexdigest())-16для 78. на виході може бути будь-яке число, не тільки-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;}

Позитивні для truthy. Негативний фальшивий результат. 0 за 0.


1
Ви можете зберегти 4 байти, видаливши forif
вкладені

1
байт в шістнадцятковому може бути golfed: 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é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 для truthy, -1 для falsey), що повинно бути досить легко, як iirc в PHP-0 === 0
Skidsdev

@Mayube, це занадто довго, на 1 байт достатньо. Найкращий спосіб - вказати вихід за можливостями мови, а не загальним
Йорг Гюльсерманн,

1
echo 16<=>strlen(preg_filter("#[0-7]#","",hash(md2,$argn)));повинен робити трюк без додаткового байта.
Крістоф

1
Версія для гольфу:<?=preg_match_all("/[0-7]/",hash(md2,$argn))<=>16;
Крістоф

@Christoph Я відчуваю себе ідіоткою, що не замислююся про preg_match_all
Jörg Hülsermann


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не є ні truthy, ні falsey. Звичайна truthy і falsey не може бути застосований до Java на цей раз (бо не може бути trueабо falseабо 0з правилом if(<truthy>)), так що я взяв на себе сміливість оголосити як такої.

Економить

  1. 137 -> 130 байт: гольф, використовуючи бітові операції, видаляючи 2 щоразу, коли я отримую "фальшивий" біт.
  2. 130 -> 124 байти: більше побітових операцій
  3. 124 -> 123 байти: замінено byteна intв оголошенні для циклу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.