Два-багато результатів


17

Змагання

Представляю вашій увазі ще одного шпигуна проти шпигунського виклику, що підкорює обскускаторів проти сухарів. Однак у цьому випадку дана, що захищається, є не входом, а результатом .

Правила виклику прості. Напишіть розпорядок із наступними характеристиками:

  1. Програма може бути написана будь-якою мовою, але не може перевищувати 320 байт.
  2. Підпрограма повинна приймати три 32-бітні цілі числа як вхідні дані. Він може мати форму функції, яка приймає 3 аргументи, функцію, яка приймає єдиний 3-елементний масив, або повну програму, яка зчитує 3 цілих числа з будь-якого стандартного вводу.
  3. Підпрограма повинна виводити одне підписане 32-бітове ціле число.
  4. На всіх можливих введеннях рутина повинна виводити між 2 і 1000 (включно) унікальних значень. Кількість унікальних значень, які може вивести рутина, називається її ключем .

Як приклад - програма С

int foo( int i1, int i2, int i3 ) {
    return 20 + (i1^i2^i3) %5;
}

має ключ 9, так як він (сподіваюся) може виводити тільки дев'ять значень 16, 17, 18, 19, 20, 21, 22, 23, і 24.

Деякі додаткові обмеження:

  1. Процедура повинна бути повністю детермінованою та інваріантною за часом, повертаючи однакові виходи для однакових входів. У рутині не повинно бути викликом генераторів псевдовипадкових чисел.
  2. Програма може не покладатися на "приховані змінні", такі як дані у файлах, системні змінні чи езотеричні особливості мови. Наприклад, підпрограми зазвичай не повинні посилатися на константи, якщо константи чітко не визначені в самому коді. Рутини, які покладаються на придумки компілятора, результати від математично невизначених операцій, арифметичні помилки тощо, також сильно не рекомендуються. Якщо сумніваєтесь, запитайте.
  3. Ви (кодер) повинні точно знати, скільки унікальних результатів може виробляти рутина, і повинні бути в змозі надати принаймні одну послідовність введення, яка виробляє кожен вихід. (Оскільки потенційно може бути сотні унікальних виходів, цей набір буде запитуватися лише у випадку оскарження вашого ключа.)

Оскільки ця проблема має набагато меншу схожість з класичним шифруванням, ніж попередня, я вважаю, що вона буде доступна широкій аудиторії.

Чим креативніше, тим краще.

Підрахунок балів

Найбільш короткі подання, що не мають тріщин, на кількість байтів будуть оголошені переможцями.

Якщо є якась плутанина, будь ласка, запитайте чи коментуйте.

Контр-виклик

Всім читачам, включаючи тих, хто подав власну процедуру, пропонується "зламати" подання. Подання буде зламано, коли його ключ розміщений у відповідному розділі коментарів. Якщо подання зберігається протягом 72 годин, не змінюючись чи не розбиваючись, воно вважається "безпечним", а будь-який наступний успіх у злому буде ігнорований заради змагань.

Допускається лише одна спроба злому на подання на кожного читача. Наприклад, якщо я подаю користувачеві X: "ваш ключ - 20", і я помиляюся, користувач X відкине мою здогадку як неправильну, і я більше не зможу надсилати додаткові здогадки для цього подання.

Зламані подання виключаються із суперечок (за умови, що вони не є "безпечними"). Їх не слід редагувати. Якщо читач бажає подати нове розпорядження, він повинен зробити це окремою відповіддю.

Оцінка зловмисника - це кількість подань (сумісних або невідповідних), які він зламає. Для сухарів з однаковими підрахунками рейтинг визначається підсумковим числом байтів у всіх тріщинах (чим вище, тим краще).

Крекер (и) з найвищим балом (и) буде оголошено переможцями разом з розробниками переможних процедур.

Будь ласка, не зламайте власне подання.

Удачі. :)

Таблиця лідерів

Останнє оновлення 2 вересня, 10:45, EST

Нерухомі бар'єри (неполамані матеріали):

  1. CJam, 105 [Денніс]

Сили, що не зупиняються (крекери):

  1. Денніс [ Ява, 269 ; C, 58 ; Математика, 29 ]
  2. Мартін Бюттнер [ Java, 245 ]

11
Чи можу я запропонувати [поліцейським і грабіжникам] теги для цих проблем? Я думаю, що це досить усталене найменування таких ігор в безпеці, і це, ймовірно, спровокує більший інтерес, ніж [змагальний].
Мартін Ендер

Звичайно. Я зараз його зміню.
COTO

Який вихід є прийнятним? STDOUT, returnі т.
Д.

2
Ваш приклад невірний; її підпис становить 9%. 5 може повернути що-небудь від -4 до 4 включно.
Кіт Рендалл

1
@Денніс, я б з вами знову спробував. Я був винен, що це було зіпсовано.
Стретч-маніяк

Відповіді:


7

CJam, 105 байт

1q~]4G#b2A#md"M-k^XM-WHM-n^GM-0%M-uwM-gM-^XeM-kM-^VO^Ph,M-^MM-^PM-qM-!M-8M-AM-OM-~tM-^FM-cM-h^AM-0M-0M-lM-@M-^[MF=M-^Z^SM-1M-KM-T2M-9M-UmSM-N
M-8M-^^M-n$4M-^M^SM-x M-OM-^@^?"256b@D#Y256#%2+md!A3#*)%)%

У наведеному вище використані карета та позначення М, оскільки вони містять недрукований символ. Після перетворення потоку байтів у ціле число ( 256b) виконується наступний код:

1q~]4G#b2A#md
12313030820310059479144347891900383683119627474072658988524821209446180284434934346766561958060381533656780340359503554566598728599799248566073353154035839
@D#Y256#%2+md!A3#*)%)%

Ви можете спробувати цю версію в Інтернеті в інтерпретаторі CJam .

Як це працює

У цьому поданні використовується теорія чисел замість обфускування. Програма поверне 0 майже для всіх входів. З небагатьох входів, які призводять до ненульового виводу, виводиться секретний модуль, який застосовується до 10 найменш значущих бітів третього цілого числа.

Найефективнішим способом вирішення цієї задачі (що я можу придумати) було б розподілення 512 бітового цілого числа, яке, сподіваюся, не буде досягнутим за 72 години.

" Prepend 1 to the numbers read from STDIN and convert the resulting array into an integer
  (“N”) by considering them digits of a base 2**32 number.                                 ";

1q~]4G#

" Compute “N / 1024” and “N % 1024”.                                                       ";

2A#md

" Push a carefully selected 512 bit semi-prime (“S”).                                      ";

12313030820310059479144347891900383683119627474072658988524821209446180284434934346766561958060381533656780340359503554566598728599799248566073353154035839

" Compute P = (N / 1024) ** 13 % 2 ** 256 + 2.                                             ";

@D#Y256#%2+

" Compute “S / P” and “S % P”.                                                             ";

md

" Compute “M = (S / P) % (1000 * !(S % P) + 1) + 1”.

  “M” is the key if P is a divisor of S; otherwise, “M == 1”.                              ";

!A3#*)%)

" Compute the final output: “N % 1024 % M”.                                                ";

%

Приклад виконання

$ base64 -d > outputs.cjam <<< MXF+XTRHI2IyQSNtZCLrGNdI7gewJfV355hl65ZPEGgsjZDxobjBz/50huPoAbCw7MCbTUY9mhOxy9QyudVtU84KuJ7uJDSNE/ggz4B/IjI1NmJARCNZMjU2IyUyK21kIUEzIyopJSkl
$ wc -c outputs.cjam
105 outputs.cjam
$ LANG=en_US cjam outputs.cjam < outputs.secret; echo
1
$ LANG=en_US cjam outputs.cjam <<< '1 2 3'; echo
0

Ти просто надто приємний із криптовалютою. ;)
COTO

11
"Ця публікація використовує теорію чисел замість обфускування." Дивиться на код "Хм, правильно".
ɐɔıʇǝɥʇuʎs

4

Ява - 269

Дякую за терпіння всім, тепер це слід виправити.

скорочено:

int a(int a,int b,int c){double d=180-360.0/(int)(Math.abs(Math.sin(a*60))*50+2),e=180-360.0/(int)(Math.abs(Math.cos(b*60))*50+2),f=180-360.0/(int)(Math.atan2(c*60, a*60)*51+2);if(Math.abs(d+e+f-360)<.1)return Integer.valueOf((int)d+""+(int)e+""+(int)f);else return 1;}

Не скорочено:

int a(int a, int b, int c) {
    double d = 180 - 360.0 / (int) (Math.abs(Math.sin(a * 60)) * 50 + 2);
    double e = 180 - 360.0 / (int) (Math.abs(Math.cos(b * 60)) * 50 + 2);
    double f = 180 - 360.0 / (int) (Math.atan2(c * 60, a * 60) * 51 + 2);
    if (Math.abs(d + e + f - 360) < .1)
        return Integer.valueOf((int) d + "" + (int) e + "" + (int) f);
    else
        return 1;
}

Можна зберегти чотири символи, змінивши double e,f,d=...;e=...;f=...;наdouble d=...,e=...,f=...;
Ypnypn

@Ypnypn Дякую! додано до версії для гольфу.
Стретч-маніяк

1
Друга спроба ( з явним дозволом ): 122
Денніс

1
@Денніс приємної роботи! (Ось так)
Maniac Stretch Maniac

1
@Dennis У цьому випадку ти забуваєш, 1і твоя відповідь також неправильна;) (123 є правильним ... хтось підійде і захопить тріщину балу ...). І я думаю, маніак Стретч не враховував, sin == 1.0коли сказав, що 122 - це правильно.
Мартін Ендер

2

Пробовідбірник

Звичайно, це не офіційний запис, і кількість персонажів занадто велика, але я думаю, якщо хтось захоче вражаючого завдання, він може спробувати визначити, скільки унікальних результатів виробляє наступна функція (з урахуванням трьох входів, як описано в ОП) :

function z(y,_,$){M=[];N=[];O=[];C=1792814437;P=72;r=t=0;(f=function(a,k,L){if(k<a.length){for(L=a[k],a[k]=0;a[k]<L;a[k]++)f(a,k+1)}else
if(!t){f([P-1,P-1],0,++t);N=M;while(t<2*P){s=!(t&1);f([P,P,P,P],0,++t);r=r||(s?0:t);t&1&&(N=O);O=[]}}else
((t<2)&&(((d=P*a[0]+(P+1)*a[1]+P)<(P<<6))&&(M[d]=(((y^~_)>>a[0])+((_^~$)>>(a[0]-32)))&1),((a[1]<P-a[0])&&
(M[a[1]+(P+1)*a[0]]=(($^C)>>a[0]+16-a[1])&1))||1))||((t&1)&&((O[P*a[2]+a[3]]|=M[a[1]+P*a[2]]&N[P*a[0]+a[3]]&&
!(a[0]-a[1]))||1))||(s|=N[(a[0]+1)*a[1]+a[3]]);})([],0,0);return r;}

Насправді я настільки впевнений, що це незбагненно, я нагороджую кожного, хто тріщить його, «Вищою нагородою за непереборну силу природи».

Бо справді вони цього заслуговують.


1
Ви повинні за це виплатити!
Орбі

1
@Orby Це було б добре, але важко присвоїти нагороду за коментар.
Геобіт


@COTO це виклик все ще триває?
Soham Chowdhury

@SohamChowdhury: Абсолютно. Якщо ви це зрозумієте, я викладу вашу перемогу в ОП. Якщо ні, дайте мені знати, і я опублікую рішення.
COTO

2

C, 58 байт (тріщини)

Простий:

f(a,b,c){return(long long)a*b*c-0x1d21344f8479d61dLL?0:a;}

2
7 ( -15485867, -1299721, -104287, 0, 104287, 1299721, 15485867).
Денніс

Це було швидко :)
Орбі

2

Ява - 245

Зламаний Мартін Бюттнер

int a(int[]_$){return $($($_(_$[0],0)))+$_(_$[1],1)*11+$($($_(_$[1+1],0)))*(1+1);}int $_(int $,int $_){int OO=0,o=1,O=1;for($=$<0?-$:$;++O*O<=$;OO+=$%O<1?O:0,o+=$%O<1?1:0,$/=$%O<1?O--:1);return $_>0?o:OO+$;}int $(int $){return(int)Math.sqrt($);}

Потік введення як Int масиву: a(new int[]{1,2,3}). Я не сподіваюся, що це пройде 72 години, але розважимось цим.

Ось це з перервами рядків, щоб зробити його трохи зрозумілішим:

int a(int[]_$){return $($($_(_$[0],0)))+$_(_$[1],
1)*11+$($($_(_$[1+1],0)))*(1+1);}int $_(int $,int
$_){int OO=0,o=1,O=1;for($=$<0?-$:$;++O*O<=$;OO+=
$%O<1?O:0,o+=$%O<1?1:0,$/=$%O<1?O--:1);return $_>
0?o:OO+$;}int $(int $){return(int)Math.sqrt($);}

Тільки від грубої сили ... 90?
Векторизований

@bitpwner Ні, вибачте.
Геобіт

1
Я трохи знеструмив це: pastebin.com/8pvvfFYB (сподіваюся, я не помилився під час заміни змінних імен.)
Martin Ender,

4
Гаразд, ось моя спроба: 965?
Мартін Ендер

1
@ MartinBüttner Правильно. Дякую за
затуманену

1

Математика, 29 байт, Ключ: 715, Розтрісканий Деннісом

Це лише фіксована версія моєї початкової відповіді, яка не працювала на позитивні дані.

f=Plus@@Mod[NextPrime@#,240]&

Бере список таких цілих чисел

f[{1,2,3}]

Я знайшов 349унікальні результати. Діапазон був від 3до 717.
PhiNotPi

@PhiNotPi Неправильно. (Я повторно перевірив)
Мартін Ендер

Ну, я знайшов свою помилку і правильну відповідь. Однак занадто пізно.
PhiNotPi

1
Якщо матеріал, який я зібрав із документації Mathematica та WolframAlpha, є правильним, ключ - 715 ( 3 ... 717).
Денніс

2
Mathematica виглядає як приємна мова, але це або занадто дорого, або я занадто дешево ...
Dennis,

0

207 символів на C / C ++, ще не затуманені:

int x(int a, int b, int c) {
    int d, e, f;
    for (int i=0; i!=1<<31; ++i) {
        d=10*(b-a);
        e=a*(28-c)-b;
        f=a*b-2.7*c;
        a += d;
        b += e;
        c += f;
    }
    return ((a%5+5)*10+(b%5+5))*10+c%5+5;
}

Тільки спробую мою везіння ... 729.
Векторизований

@bitpwner Чорт, я просто збирався це сказати. : D ... Якщо це неправильно, це верхня межа, хоча.
Мартін Ендер

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