Какие символы чаще встречаются в моем хэше MD2?


11

Задача проста

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

01234567 - (positive)
89abcdef - (negative)
  • Ввод всегда будет строкой, но может иметь любую длину до 65535
  • Весь ввод, пробелы и все, должны быть хэшированы
  • Для целей этой задачи целое число 0 не считается ни положительным, ни отрицательным (см. Вывод по связи)
  • Более распространенным набором является тот, чьи символы чаще встречаются в шестнадцатеричной хэш-строке из 32 символов.
  • Ваш вывод может содержать конечные пробелы любого вида, при условии, что единственные непробельные символы являются действительными выводами true или false
  • В случае связи, где шестнадцатеричная строка содержит ровно 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 будет делать!
Скидсдев

Я думаю, что было бы справедливо просто принять три различных значения: победа , поражение и ничья
математика наркоман

@mathjunkie правда, вероятно, не стоит так сильно менять спецификацию, но я думаю, лучше всего иметь 1, 0 или -1
Skidsdev

2
Это кажется мне вызовом хамелеона . Либо у вашего языка есть встроенная библиотека или библиотека для MD2, а остальное - просто подсчет символов, либо его нет, и вы должны реализовать его самостоятельно.
xnor

Ответы:


1

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

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

* Требуется последняя версия Octave (минимум 4.2).

Вычисляет историю хеш-строки с центром бинов 7 и 8, а затем вычисляет разницу в количестве.


Учитывая, что прошло несколько дней, я выложу ваш ответ как победный, если кто-то позже предложит более короткое решение, я всегда могу его изменить. Отлично сработано!
Скидсдев

@Mayube Спасибо!
rahnema1


8

JavaScript (ES6), 731 байт

Этот монстр реализует алгоритм MD2, поэтому он очень длинный. Основано на 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, а не использовать встроенные функции.
Скидсдев

Ответ старшего байта заслуживает большего количества очков.
Волшебная Урна Осьминога

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 благодаря дзайме

-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
Вы можете сохранить 4 байта, удалив скобки forиif
dzaima

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 для true, -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
Йорг Хюльсерманн


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 не может быть применен к 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.