Шафки проти крекерів: П’ятиелементна послідовність


31

Змагання

Простий виклик "шпигун проти шпигуна".

Напишіть програму з такими специфікаціями:

  1. Програма може бути написана будь-якою мовою, але не повинна перевищувати 512 символів (як це представлено в блоці коду на цьому сайті).
  2. Програма повинна приймати 5 підписаних 32-бітних цілих чисел як вхідні дані. Він може мати форму функції, яка приймає 5 аргументів, функцію, яка приймає єдиний 5-елементний масив, або повну програму, яка зчитує 5 цілих чисел з будь-якого стандартного вводу.
  3. Програма повинна вивести одне підписане 32-бітове ціле число.
  4. Програма повинна повернути 1, якщо і лише тоді, якщо п’ять входів, інтерпретованих як послідовність, відповідають певній арифметичній послідовності вибору програміста, що називається "ключем". Функція повинна повертати 0 для всіх інших входів.

Арифметична послідовність має властивість, що кожен наступний елемент послідовності дорівнює попереднику плюс деяка фіксована константа a.

Наприклад, 25 30 35 40 45це арифметична послідовність, оскільки кожен елемент послідовності дорівнює попереднику плюс 5. Аналогічно 17 10 3 -4 -11це арифметична послідовність, оскільки кожен елемент дорівнює його попереднику плюс -7.

Послідовності 1 2 4 8 16і 3 9 15 6 12не є арифметичними послідовностями.

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

Наприклад, припустимо, ви обираєте ключ 98021 93880 89739 85598 81457. Ваша програма повинна повернути 1, якщо входи (послідовно) відповідають цим п'яти числам, а 0 - в іншому випадку.

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

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

Переможцем буде оголошено найкоротший поданий без розриву на кількість символів.

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

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

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

Докладнішу інформацію щодо оновленої політики щодо розбиття балів див. У розділі "Відмова" нижче.

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

Злам (и) з найвищим балом (і) будуть оголошені переможцями разом із розробниками програм-переможців.

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

Удачі. :)

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

Передостаннє класифікація (очікує на безпеку подання Денніса на CJam 49).

Безпечні шафки

  1. CJam 49, Денніс
  2. CJam 62, Денніс сейф
  3. CJam 91, Денніс сейф
  4. Python 156, Maarten Baert сейф
  5. Perl 256, чилімагічний сейф
  6. Java 468, Геобіт безпечний

Крекери без зупинки

  1. Пітер Тейлор [Ruby 130, Java 342, Mathematica 146 *, Mathematica 72 *, CJam 37]
  2. Денніс [Pyth 13, Python 86 *, Lua 105 *, GolfScript 116, C 239 *]
  3. Мартін Бюттнер [Javascript 125, Python 128 *, Ruby 175 *, Ruby 249 *]
  4. Тіїло [C 459, Javascript 958 *]
  5. freddieknets [Mathematica 67 *]
  6. Ільмарі Каронен [Python27 182 *]
  7. азотний [C 212 *]

* невідповідність подання

Відмова (оновлено 23:15 EST, 26 серпня)

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

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

Мої вибачення за внесення змін до правил цього пізно в грі.


6
Як ви збираєтеся перевірити, що програми відповідають пункту 4? Чи очікуєте, що люди відредагують свої безпечні відповіді, щоб додати доказ? Чи дозволені імовірнісні подання на основі припущення, що хеш-функції ідеальні, а ймовірність зіткнення з іншим елементом 48-бітного (за вашою оцінкою вище) простору незначна?
Пітер Тейлор

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

3
@COTO Я думаю, що проблема полягає в тому, що ви можете отримати лише 2 баламутні оцінки, і лише найкоротші. То чому б не чекати і сподіватися і довше з'являтися? Наприклад, у Мартіна зараз немає стимулу зламати мій (довший) замок, оскільки він уже зламав дві коротші. Кожен, хто зламає мій, тепер битиме його, навіть не вимагаючи другого.
Геобіц

1
Я думаю, що краща система підрахунку балів може бути сумою загального часу між питаннями та тріщинами. Таким чином, зламати купу легких можна побити, а справжня винагорода виходить за розтріскування справді важких.
isaacg

1
Я новачок у гольфі, тож, можливо, це дурне питання, вибачте за це. Чому довжина коду вимірюється символами, а не байтами? Останнє - це буквально простір пам'яті, який займає програма, тому для мене це здається більш логічним. Напр. відповідь CJam є найкоротшою за символами, але, дивлячись на її розмір (326 через unicode), він навіть не в топ 5. Тож мені цікаво, чи є загальною умовою в гольфі рахувати символи замість байтів?
freddieknets

Відповіді:


3

CJam, 62 символи

"ḡꬼ쏉壥떨ሤ뭦㪐ꍡ㡩折量ⶌ팭뭲䯬ꀫ郯⛅彨ꄇ벍起ឣ莨ຉᆞ涁呢鲒찜⋙韪鰴ꟓ䘦쥆疭ⶊ凃揭"2G#b129b:c~

Stack Exchange схильний до маніпулювання недрукованих символів, але копіює код із цієї пасти та вставляє її в інтерпретатор CJam добре працює для мене.

Як це працює

Після заміни рядка Unicode рядком ASCII виконується такий код:

" Push 85, read the integers from STDIN and collect everything in an array.               ";

85l~]

" Convert the array of base 4**17 digits into and array of base 2 digits.                 ";

4H#b2b

" Split into chunks of length 93 and 84.                                                  ";

93/~

" Do the following 611 times:

    * Rotate array A (93 elements) and B one element to the left.
    * B[83] ^= B[14]
    * T = B[83]
    * B[83] ^= B[0] & B[1] ^ A[23]
    * A[92] ^= A[26]
    * Rotate T ^ A[92] below the arrays.
    * A[92] ^= A[0] & A[1] ^ B[5].                                                        ";

{(X$E=^:T1$2<:&^2$24=^+\(1$26=^_T^@@1$2<:&^3$5=^+@}611*

" Discard the arrays and collects the last 177 generated bits into an array.              ";

;;]434>

" Convert the into an integer and check if the result is 922 ... 593.                     ";

2b9229084211442676863661078230267436345695618217593=

Цей підхід використовує Bivium-B (див. Алгебраїчний аналіз тривієподібних шифрів ), ослаблену версію потокового шифру Trivium .

Програма використовує послідовність цілих чисел як початковий стан, оновлює стан 434 рази (354 раунди досягають повної дифузії) і генерує 177 біт виводу, який вона порівнює з послідовностями правильної послідовності.

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

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

$ echo $LANG
en_US.UTF-8
$ base64 -d > block.cjam <<< IgThuKHqrLzsj4nlo6XrlqjhiKTrrabjqpDqjaHjoanmipjvpb7itozuoIDtjK3rrbLul7bkr6zqgKvvjafpg6/im4XlvajqhIfrso3uprrotbfvmL/hnqPojqjguonhhp7mtoHujLPuipzlkaLpspLssJzii5npn6rpsLTqn5PkmKbspYbnlq3itorlh4Pmj60iMkcjYjEyOWI6Y34=
$ wc -m block.cjam
62 block.cjam
$ cjam block.cjam < block.secret; echo
1
$ cjam block.cjam <<< "1 2 3 4 5"; echo
0

6

CJam, 91 персонаж

q~]KK#bD#"᫖࿼듋ޔ唱୦廽⻎킋뎢凌Ḏ끮冕옷뿹毳슟夫΢眘藸躦䪕齃噳卤"65533:Bb%"萗縤ᤞ雑燠Ꮖ㈢ꭙ㈶タ敫䙿娲훔쓭벓脿翠❶셭剮쬭玓ୂ쁬䈆﹌⫌稟"Bb=

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

Як це працює

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

" Read the integers from STDIN and collect them in an array.                               ";

q~]

" Convert it into an integer by considering its elements digits of a base 20**20 number.   ";

KK#b

" Elevate it to the 13th power modulus 252 ... 701.                                        ";

D#
25211471039348320335042771975511542429923787152099395215402073753353303876955720415705947365696970054141596580623913538507854517012317194585728620266050701%

" Check if the result is 202 ... 866.                                                      ";

20296578126505831855363602947513398780162083699878357763732452715119575942704948999334568239084302792717120612636331880722869443591786121631020625810496866=

Оскільки 13 є спільним для сукупності модуля (коєфіцієнт є секретним, тому вам просто доведеться довіряти мені), різні бази дадуть різні результати, тобто рішення унікальне.

Якщо хтось не може використати малий показник (13), найефективніший спосіб зламати цей замок - це факторизувати модуль (див. Проблему RSA ). Я вибрав для модуля 512-бітове ціле число, яке повинно витримати 72 години спроб факторизації.

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

$ echo $LANG
en_US.UTF-8
$ base64 -d > lock.cjam <<< cX5dS0sjYkQjIgHuiJHhq5bgv7zrk4velOWUse6zjuCtpuW7veK7ju2Ci+uOouWHjOG4ju+Rh+uBruWGleyYt+u/ueavs+6boOyKn+Wkq86i55yY6Je46Lqm5KqV6b2D5Zmz75Wp5Y2kIjY1NTMzOkJiJSIB6JCX57ik4aSe74aS6ZuR54eg4Y+G44ii6q2Z44i244K/5pWr5Jm/5aiy7ZuU7JOt67KT7rO26IS/57+g4p2275+K7IWt5Ymu7Kyt546T4K2C7IGs5IiG77mM4quM56ifIkJiPQ==
$ wc -m lock.cjam
91 lock.cjam
$ cjam lock.cjam < lock.secret; echo
1
$ cjam lock.cjam <<< "1 2 3 4 5"; echo
0

Я опублікував нову версію, оскільки забув видалити непотрібний символ із першої. Секретна послідовність все одно однакова, тому ви можете спробувати зламати будь-яку.
Денніс

FYI, я припиняю свою спробу факторингу. msieve встановив собі обмеження в часі 276 годин, але це було лише для побудови факторної бази. У той час це found 1740001 rational and 1739328 algebraic entries; минуло майже 100 годин на їх обробку та звіти sieving in progress b = 46583, 0 complete / 0 batched relations (need 44970493).
Пітер Тейлор

@PeterTaylor: Схоже, 512 біт був надмірним. Ви намагалися ввести чисельне число в іншій моїй відповіді чи в цій?
Денніс

Ой, ой. Так, інший.
Пітер Тейлор

4

Пітон - 128

Спробуємо це:

i=input()
k=1050809377681880902769L
print'01'[all((i>1,i[0]<i[4],k%i[0]<1,k%i[4]<1,i[4]-i[3]==i[3]-i[2]==i[2]-i[1]==i[1]-i[0]))]

(Очікує, що користувач введе 5 цифр, розділених комами, наприклад 1,2,3,4,5.)


3
32416190039,32416190047,32416190055,32416190063,32416190071
Мартін Ендер

Ого, це було швидко! Ти правий! І я виходжу.
Фалько

3
До речі, це насправді не вірно, тому що ваші п'ять цілих чисел не вміщуються в 32-бітове ціле число.
Мартін Ендер

4

Ява: 468

Вхід подається як k(int[5]). Заборгованість рано, якщо не рівномірно розташована. В іншому випадку потрібно трохи з'ясувати, чи правильно всі десять хешів. Для великої кількості "трохи" може означати десять секунд або більше, тому це може відвернути сухариків.

//golfed
int k(int[]q){int b=q[1]-q[0],i,x,y,j,h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,998860524,888446062,1833324980,1391496617,2075731831};for(i=0;i<4;)if(q[i+1]-q[i++]!=b||b<1)return 0;for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));for(i=0;i<5;i++){for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));if(x!=h[i*2]||y!=h[i*2+1])return 0;}return 1;}int m(int a,int b,int c){long d=1;for(;b-->0;d=(d*a)%c);return (int)d;}

// line breaks
int k(int[]q){
    int b=q[1]-q[0],i,x,y,j,
    h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,
                  998860524,888446062,1833324980,1391496617,2075731831};
    for(i=0;i<4;)
        if(q[i+1]-q[i++]!=b||b<1)
            return 0;
    for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));
    for(i=0;i<5;i++){
        for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));
        if(x!=h[i*2]||y!=h[i*2+1])
            return 0;
    }
    return 1;
}
int m(int a,int b,int c){
    long d=1;for(;b-->0;d=(d*a)%c);
    return (int)d;
}

1
Ваш код висить, якщо арифметична послідовність вводу зменшується. Або, принаймні, займає дійсно тривалий час. Що змушує мене думати, що секретний код зростає ...
Кіт Рендалл

3
@KeithRandall На жаль Додамо чотири байти, щоб низхідні послідовності зайняли незвично короткий проміжок часу, ще більше посиливши вашу віру.
Геобіц

4

Ява: 342

int l(int[]a){String s=""+(a[1]-a[0]);for(int b:a)s+=b;char[]c=new char[11];for(char x:s.toCharArray())c[x<48?10:x-48]++;for(int i=0;i<11;c[i]+=48,c[i]=c[i]>57?57:c[i],i++,s="");for(int b:a)s+=new Long(new String(c))/(double)b;return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;}

Ось шафа на основі рядків, яка залежить як від кількості вхідних символів, так і від конкретного вводу. Послідовність може базуватися на неясних посиланнях на поп-культуру. Веселіться!

Трохи необурений:

int lock(int[]a){
    String s=""+(a[1]-a[0]);
    for(int b:a)
        s+=b;
    char[]c=new char[11];
    for(char x:s.toCharArray())
        c[x<48?10:x-48]++;
    for(int i=0;i<11;c[i]+=48,
                     c[i]=c[i]>57?57:c[i],
                     i++,
                     s="");
    for(int b:a)
        s+=new Long(new String(c))/(double)b;
    return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;
}

2
8675309? 90210?
Малахій

1
@Malachi Дві видатні посилання, без сумніву, але я не можу ні підтвердити, ні заперечити їх застосовність до цієї вправи.
Геобіт

хаха, я ще не до кінця зрозумів, як працює цей виклик повністю, я можу дати йому пізніше, коли я вдома.
Малахій

1
Початковий термін - -8675309дельта 5551212.
Пітер Тейлор

@PeterTaylor Чудово зроблено :)
Geobits

4

Пітона, 147

Редагувати: скорочена версія на основі коментаря Денніса. Я також оновив послідовність, щоб уникнути витоку будь-якої інформації.

def a(b):
    c=1
    for d in b:
        c=(c<<32)+d
    return pow(7,c,0xf494eca63dcab7b47ac21158799ffcabca8f2c6b3)==0xa3742a4abcb812e0c3664551dd3d6d2207aecb9be

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


Дискретні логарифми набагато складніше, що я думав. Мій зломщик був на цьому вже 26 годин. Я здаюся.
Денніс

Ви можете вирішити проблему знаків шляхом ініціалізації c=1, обчислення c=(c<<32)+dта зміни константи відповідно.
Денніс

3

Javascript 125

Цей має бути зламаний досить швидко. Я продовжуватиму щось сильніше.

function unlock(a, b, c, d, e)
{
    return (e << a == 15652) && (c >> a == 7826) && (e - b == d) && (d - c - a == b) ? 1 : 0;
}

6
0, 3913, 7826, 11739, 15652
Мартін Ендер

так, ти це зрозумів :)
rdans

3

Рубі, 175

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
p a[2]*(a[1]^a[2]+3)**7==0x213a81f4518a907c85e9f1b39258723bc70f07388eec6f3274293fa03e4091e1?1:0

На відміну від використання криптографічного хешу srand, це, очевидно, унікально (що є незначною підказкою). Бере п'ять цифр через STDIN, розмежований будь-яким нецифровим, неновим рядком або символами. Виводи в STDOUT.


Так, забули, що вони підписалися.
гістократ

2
622238809,1397646693,2173054577,2948462461,3723870345(моя попередня здогадка мала помилку, але ця перевірена). Я не думаю, що це дійсно, тому що останнє число не вписується у підписане 32-бітове ціле число.
Мартін Ендер

3

GolfScript (116 символів)

Вводить дані як цілі числа, розділені пробілом.

~]{2.5??:^(&}%^base 2733?5121107535380437850547394675965451197140470531483%5207278525522834743713290685466222557399=

2
-51469355 -37912886 -24356417 -10799948 2756521
Денніс

Хороша робота. Ви експлуатували малу експонентку?
Пітер Тейлор

2
Ні, я розподілив модуль. Взяв лише 13 секунд, використовуючи кілька поліноміальних квадратичних сит приміток і PyPy.
Денніс

У такому випадку я можу також відмовитися від свого поточного гольфу, використовуючи компактно виражений модуль. Якщо результат повинен бути чимось на зразок 1024 біт, щоб бути захищеним від факторингу, то навіть за допомогою представлення базової 256 це буде занадто довго.
Пітер Тейлор

Я сподіваюся, що не. Моя відповідь використовує ту саму ідею, що і ваша, але з 512 бітовим модулем і ще меншим показником (13). Враховуючи часовий обмеження 72 години, цього, можливо, буде достатньо ...
Денніс

3

C 459 байт

ВИРІШЕНИЙ ТИЙЛО - ЧИТАЙТЕ НЕОБХІДНО

int c (int* a){
int d[4] = {a[1] - a[0], a[2] - a[1], a[3] - a[2], a[4] - a[3]};
if (d[0] != d[1] || d[0] != d[2] || d[0] != d[3]) return 0;
int b[5] = {a[0], a[1], a[2], a[3], a[4]};
int i, j, k;
for (i = 0; i < 5; i++) { 
for (j = 0, k = 2 * i; j < 5; j++, k++) {
k %= i + 1;
b[j] += a[k];
}
}
if (b[0] == 0xC0942 - b[1] && 
b[1] == 0x9785A - b[2] && 
b[2] == 0x6E772 - b[3] && 
b[3] == 0xC0942 - b[4] && 
b[4] == 0xB6508 - b[0]) return 1;
else return 0;
}

Нам потрібен хтось, щоб написати рішення C, чи не так? Я не вражаю нікого довжиною, я не гольфіст. Я сподіваюся, що це цікавий виклик!

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

int main(){
    a[5] = {0, 0, 0, 0, 0} /* your guess */
    printf("%d\n", c(a));
    return 0;
}

PS Є важливе значення a[0] як число саме по собі, і я хотів би, щоб хтось це зазначив у коментарях!

Редагувати:

Рішення: 6174, 48216, 90258, 132300, 174342

Примітка про розтріскування:

Хоча це не метод, який застосовується (див. Коментарі), мені трапилось зламати власний шифр із дуже легкою грубою силою. Я розумію, що зараз важливо зробити кількість великими. Наступний код може зламати будь-який шифр, де upper_boundце відома верхня межа a[0] + a[1] + a[2] + a[3] + a[4]. Верхня межа вищевказаного шифру є 457464, яка може бути отримана з системи рівнянь b[]і деякого опрацювання алгоритму. Можна показати, що b[4] = a[0] + a[1] + a[2] + a[3] + a[4].

int a[5];
for (a[0] = 0; a[0] <= upper_bound / 5; a[0]++) {
    for (a[1] = a[0] + 1; 10 * (a[1] - a[0]) + a[0] <= upper_bound; a[1]++) {
        a[2] = a[1] + (a[1] - a[0]);
        a[3] = a[2] + (a[1] - a[0]);
        a[4] = a[3] + (a[1] - a[0]);
        if (c(a)) {
            printf("PASSED FOR {%d, %d, %d, %d, %d}\n", a[0], a[1], a[2], a[3], a[4]);
        }
    }
    printf("a[0] = %d Checked\n", a[0]);
}

З a[0] = 6174, ця петля зламала мою роботу за трохи менше хвилини.


6
Рішення 6174, 48216, 90258, 132300, 174342.
Тайло

Нічого собі, це було швидко. Хороший. Наполегливо, чи ти знайшов щось розумне, що я пропустив?
BrainSteel

Я використав символічну оцінку Mathematica, наприклад: ghostbin.com/paste/jkjpf screenshot: i.imgur.com/2JRo7LE.png
Тайло

Знову редагуйте: я в основному робив те ж саме, але погладив верхню частину в 500k. Отримав відповідь і побачив, що Тиїло вже опублікував це :(
Геобіт,

@Geobits Це дивно здогадка. Потрібно було поставити ще кілька знаків 0 на кінцях цих чисел.
BrainSteel

3

Математика 80 67

f=Boole[(p=NextPrime/@#)-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&

Запуск:

f[{1,2,3,4,5}] (* => 0 *)

Можливо, досить легко зламати, може також мати декілька рішень.

Оновлення: Поліпшення гольфу, виконуючи те, що запропонував Мартін Бюттнер. Функціональність функції та клавіша не змінилася.


@ MartinBüttner Покращення відповідей, щоб отримати більш високий бал, коли ви їх зламаєте. Smart; P
Тайло

Ага, виявляється, я пропустив абзац про забиття контратаки. Я подумав, що це просто для задоволення від цього, без будь-якої оцінки. Хоча я не думаю, що для мене було б сенсом скорочувати рішення, які я хочу зламати, тому що це знизить мою оцінку.
Мартін Ендер

4
{58871,5592,-47687,-100966,-154245}
freddieknets

@freddieknets Не рішення, яке я використовував при його створенні. Не знав, що NextPrimeможе повернути негативні значення. Як ти його знайшов?
Тайло

Тоді ваш ключ не унікальний: p. Я просто провів кілька тестів - насправді не так багато цифр, де NextPrime [#] - # оцінює 31, тож це простий спосіб зламати його.
freddieknets

2

Python27, 283 182

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

import sys
p=1
for m in map(int,sys.argv[1:6]):m*=3**len(str(m));p*=m<<sum([int(str(m).zfill(9)[-i])for i in[1,3,5,7]])
print'01'[p==0x4cc695e00484947a2cb7133049bfb18c21*3**45<<101]

редагувати: Завдяки colevk для подальшого гольфу. Під час редагування я зрозумів, що в моєму алгоритмі є помилка та недолік, можливо, наступного разу мені пощастить.


5
Це є інваріантним при перепорядкуванні аргументів, тому це не є дійсним шафкою.
Пітер Тейлор

Крім того, я підозрюю, що код розміщений є баггі: ключ 121174841 121174871 121174901 121174931 121174961працює, але тільки якщо список [1,3,5,7]у рядку 7 замінено на [1,3,5,7,11].
Ільмарі Каронен

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

Actually, finding and fixing the bug was the difficult part; given your algorithm, factoring the constant was kind of an obvious thing to try.
Ilmari Karonen

2

Mathematica 142 146

EDIT: key wasn't unique, added 4 chars, now it is.

n=NextPrime;
f=Boole[
    FromDigits /@ (
        PartitionsQ[n@(237/Plus@##) {1, ##} + 1] & @@@ 
            IntegerDigits@n@{Plus@##-37*Log[#3],(#1-#5)#4}
    ) == {1913001154,729783244}
]&

(Spaces and newlines added for readability, not counted & not needed).

Usage:

f[1,2,3,4,5]   (* => 0 *)

1
Initial term 256208, delta -5.
Peter Taylor

Dang, then still it isn't unique, as this isn't my original key. Did you bruteforce?
freddieknets

Test it, I might have made a mistake because I don't have access to Mathematica to test. Each stage is using brute force, but it's not much computer time. The approach is to work backwards to the output of IntegerDigits and then factor to get candidates for the initial term and delta.
Peter Taylor

But there's no way this approach could be unique anyway. The second of the five inputs is only used in a sum which is passed to NextPrime; if we vary it by plus or minus one, at least one of those will give the same next prime.
Peter Taylor

yes but for a arithmetic sequence -as is the required input- it was supposed to be unique.
freddieknets

1

Cracked by @Dennis in 2 hours


Just a simple one to get things started - I fully expect this to be quickly cracked.

Pyth, 13

h_^ZqU5m-CGdQ

Takes comma separated input on STDIN.

Run it like this (-c means take program as command line argument):

$ echo '1,2,3,4,5' | python3 pyth.py -c h_^ZqU5m-CGdQ
0

Fixed the program - I had not understood the spec.

This language might be too esoteric for this competition - If OP thinks so, I will remove it.


7
Have you just given away that 1,2,3,4,5 is the key?
Peter Taylor

1
Every input I tried returned 1, did you switch 1 and 0 as output?
Tyilo

Sorry, I didn't understand the Output vs. Return distinction - the program should work now. Same underlying algorithm.
isaacg

3
97,96,95,94,93 (I just killed my cracking score.)
Dennis

@Dennis Well done. The cracking score system needs to be changed - it's creating some really weird incentives.
isaacg

1

Lua 105

I suspect it won't be long before it's cracked, but here we go:

function f(a,b,c,d,e)
   t1=a%b-(e-2*(d-b))
   t2=(a+b+c+d+e)%e
   t3=(d+e)/2
   print(t1==0 and t2==t3 and"1"or"0")
end

(spaces added for clarity, but are not part of count)


3, 7, 11, 15, 19 or 6, 14, 22, 30, 38
Dennis

@Dennis: sadly it is neither of those. I'll have to work on it a bit later to ensure the non-uniqueness.
Kyle Kanos

t1==0 whenver S is increasing. Also, both conditions are homogeneous; if S is a solution, so is kS.
Dennis

1

Perl - 256

sub t{($z,$j,$x,$g,$h)=@_;$t="3"x$z;@n=(7,0,split(//,$g),split(//,$h),4);@r=((2)x6,1,1,(2)x9,4,2,2,2);$u=($j+1)/2;for$n(0..$#r+1){eval{substr($t,$j,1)=$n[$n]};if($@){print 0; return}$j+=$r[$n]*$u}for(1..$x){$t=pack'H*',$t;}eval$t;if($@||$t!~/\D/){print 0}}

I had to put in a lot of error handling logic and this can definitely be golfed down a lot more. It will print a 1 when you get the right five numbers. It will hopefully print a 0 for everything else (might be errors or nothing, I don't know). If anyone wants to help improve the code or golf it more, feel free to help out!


Call with:

t(1,2,3,4,5);

1

Ruby - 130

Based on Linear Feedback Shift Register. Inputs by command line arguments.
Should be unique based on the nature of LFSRs. Clue: ascending and all positive.

Will give more clues if no one solves it soon.

x=($*.map{|i|i.to_i+2**35}*'').to_i
(9**8).times{x=((x/4&1^x&1)<<182)+x/2}
p x.to_s(36)=="qnsjzo1qn9o83oaw0a4av9xgnutn28x17dx"?1:0

3
Initial value 781783, increment 17982811
Peter Taylor

@PeterTaylor Argh... =)
Vectorized

1

Ruby, 249

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
r=(a[0]*a[1]).to_s(5).tr'234','(+)'
v=a[0]<a[1]&&!r[20]&&(0..3).select{|i|/^#{r}$/=~'%b'%[0xaa74f54ea7aa753a9d534ea7,'101'*32,'010'*32,'100'*32][i]}==[0]?1:0rescue 0
p v

Should be fun. Who needs math?


2
309, 77347, 154385, 231423, 308461 but I don't think it's unique.
Martin Ender

Yeah, it's not. For the same regex (i.e. product of the first two numbers), I also find 103, 232041, 463979, 695917, 927855 and 3, 7966741, 15933479, 23900217, 31866955. And I'm pretty sure there are other valid regexes by using additional +s.
Martin Ender

Sorry, I guess I messed up the test string. There was supposed to be only one regexp with a unique factorization.
histocrat

If you want to try to fix it, make sure to take possessive quantifiers into account. I can also create a larger, equivalent regex by inserting () or similar.
Martin Ender

1

CJam, 49 characters

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b[1q~]8H#b%!

Try it online.

How it works

" Push a string representing a base 65536 number and convert it to an integer.            ";

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b

" Prepend 1 to the integers read from STDIN and collect them into an array.               ";

[1q~]

" Convert that array into an integer by considering it a base 2**51 number.               ";

8H#b

" Push the logical NOT of the modulus of both computed integers.                          ";

%!

The result will be 1 if and only if the second integer is a factor of the first, which is a product of two primes: the one corresponding to the secret sequence and another that doesn't correspond to any valid sequence. Therefore, the solution is unique.

Factorizing a 512 bit integer isn't that difficult, but I hope nobody will be able to in 72 hours. My previous version using a 320 bit integer has been broken.

Example run

$ echo $LANG
en_US.UTF-8
$ base64 -d > flock512.cjam <<< IuiFleyYoeijg+SDrOqvs+uEkNaa76a/5b6L4KGG4ZOF76Gi46WE64eu4pSO5JSk5ayj6pGZ5Ji/7Zy64aWw57GD5YO+7I6n6Kuv65aG7qK04byr6aS+6IWO7rSn7YuvIjJHI2JbMXF+XThII2IlIQ==
$ wc -m flock512.cjam
49 flock512.cjam
$ cjam flock512.cjam < flock512.secret; echo
1
$ cjam flock512.cjam <<< "1 2 3 4 5"; echo
0

I've had msieve running on it for over 24 hours, but since its self-imposed time limit is 276.51 CPU-hours and I've only given it one CPU I'm not optimistic.
Peter Taylor

0

Javascript 958

Converts the inputs to a number of data types and performs some manipulations relevant to each data type along the way. Should be fairly easily reversed for anyone that takes the time.

function encrypt(num)
{
    var dateval = new Date(num ^ (1024-1) << 10);

    dateval.setDate(dateval.getDate() + 365);

    var dateString = (dateval.toUTCString() + dateval.getUTCMilliseconds()).split('').reverse().join('');

    var result = "";

    for(var i = 0; i < dateString.length; i++)
        result += dateString.charCodeAt(i);

    return result;
}

function unlock(int1, int2, int3, int4, int5)
{
    return encrypt(int1) == "5549508477713255485850495848483249555749321109774324948324410511470" && encrypt(int2) == "5756568477713252485848495848483249555749321109774324948324410511470" && encrypt(int3) == "5149538477713248485856485848483249555749321109774324948324410511470" && encrypt(int4) == "5356498477713256535853485848483249555749321109774324948324410511470" && encrypt(int5) == "5748568477713251535851485848483249555749321109774324948324410511470" ? 1 : 0;
}

5
Brute forced: 320689, 444121, 567553, 690985, 814417
Tyilo

@Tyilo If you stop now, I think no cracker can beat your score. ;)
Martin Ender

2
@MartinBüttner Unless this can be golfed to under 512 per the OP, I don't think it counts.
Geobits

0

C, 239 (Cracked by Dennis)

Go here for my updated submission.

Could probably be golfed a little more thoroughly. Admittedly, I haven't taken the time to prove the key is unique (it probably isn't) but its definitely on the order of a hash collision. If you crack it, please share your method :)

p(long long int x){long long int i;x=abs(x);
for (i=2;i<x;i++) {if ((x/i)*i==x) return 0;}return 1;}
f(a,b,c,d,e){char k[99];long long int m;sprintf(k,"%d%d%d%d%d",e,d,c,b,a);
sscanf(k,"%lld",&m);return p(a)&&p(b)&&p(c)&&p(d)&&p(e)&&p(m);}

1
So, 0 0 0 0 0?
Dennis

Sigh that was a bug, but yes that works.
Orby

I've updated with a corrected version that should be a little more interesting ;)
Orby

See the corrected version here.
Orby

0

C, 212 by Orby -- Cracked

https://codegolf.stackexchange.com/a/36810/31064 by Orby has at least two keys:

13 103 193 283 373
113 173 233 293 353

Orby asked for the method I used to crack it. Function p checks whether x is prime by checking x%i==0 for all i between 2 and x (though using (x/i)*i==x instead of x%i==0), and returns true if x is a prime number. Function f checks that all of a, b, c, d and e are prime. It also checks whether the number m, a concatenation of the decimal representations of e, d, c, b and a (in that order), is prime. The key is such that a,b,c,d,e and m are all prime.

Green and Tao (2004) show that there exist infinitely many arithmetic sequences of primes for any length k, so we just need to look for these sequences that also satisfy m being prime. By taking long long as being bounded by -9.223372037e+18 and 9.223372037e+18, we know that for the concatenated string to fit into long long, the numbers have an upper bound of 9999. So by using a python script to generate all arithmetic sequences within all primes < 10000 and then checking whether their reverse concatenation is a prime, we can find many possible solutions.

For some reason I came up with false positives, but the two above are valid according to the program. In addition there may be solutions where e is negative and the rest are positive (p uses the modulus of x), but I didn't look for those.

The keys I gave are all arithmetic sequences but Orby's script doesn't appear to actually require the inputs to be an arithmetic sequence, so there may be invalid keys too.


0

MATLAB: Apparently invalid

Very simple, you just have to generate the right random number.

function ans=t(a,b,c,d,e)
rng(a)
r=@(x)rng(rand*x)
r(b)
r(c)
r(d)
r(e)
rand==0.435996843156676

It can still error out, but that shouldn't be a problem.


1
This approach is prohibited in the comments. If it's not mentioned in the question, propose an edit. Sorry.
Peter Taylor

@PeterTaylor I guess I am out then, I will just leave it here without score as I am curious whether someone can find a weakness.
Dennis Jaheruddin

0

MATLAB (with Symbolic Toolbox), 173 characters

This isn't an official entry and won't count towards anyone's cracking score, but it will net you mad bragging rights. ;)

function b=L(S),c=sprintf('%d8%d',S(1),S(2)-S(1));b=numel(unique(diff(S)))==1&&numel(c)==18&&all(c([8,9])==c([18,17]))&&isequal(c,char(sym(sort(c,'descend'))-sym(sort(c))));

The symbolic toolbox is only required to handle subtraction of big integers.

Brute forcing it should be a dog, but if you're familiar with the series it involves, the solution is trivial.


0

Python 2 (91)

Edit: This isn't allowed because the argument for uniqueness is probabilistic. I give up.


s=3
for n in input():s+=pow(n,s,7**58)
print s==0x8b5ca8d0cea606d2b32726a79f01adf56f12aeb6e

Takes lists of integers as input, like [1,2,3,4,5].

The loop is meant to operate on the inputs in an annoying way, leaving a tower of sums and exponents. The idea is like discrete log, but with messy complication instead of mathematical simplicity. Maybe the compositeness of the of the modulus is a vulnerability, in which case I could make it something like 7**58+8.

I don't really know how I'd prove that my key is the only one, but the range of outputs is at least 10 times bigger than the range of inputs, so probably? Though maybe only a small fraction of potential outputs are achievable. I could always increase the number of digits at the cost of characters. I'll leave it up to you to decide what's fair.

Happy cracking!


0

Mathematica - 72

Version 2 of my script, with the same key as the one intended for my version 1.

This basically removes negative prime numbers for NextPrime.

f=Boole[(p=Abs[NextPrime/@#])-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&

Running:

f[{1,2,3,4,5}] (* => 0 *)

Assuming that I've correctly understood what your code does, I get several solutions of which the smallest is initial term 9244115, delta 25.
Peter Taylor

@PeterTaylor I can confirm that that one is valid.
Martin Ender

@PeterTaylor correct, another key is 1073743739, 1073886396, 1074029053, 1074171710, 1074314367
Tyilo

0

Python, 86 characters

a,b,c,d,e=input()
print 1if(a*c^b*e)*d==0xd5867e26a96897a2f80 and b^d==48891746 else 0

Enter the numbers like 1,2,3,4,5.

> python 36768.py <<< "1,2,3,4,5"
0
> python 36768.py <<< "[REDACTED]"
1

This isn't a valid submission; it accepts the input 1,0,1,63021563418517255630720,0.
Dennis

@Dennis Fixed. I hope it's valid now.
Snack

1
19960211, 31167202, 42374193, 53581184, 64788175
Dennis

@Dennis Correct and awesome. I think I'm very poor at math.
Snack

2
@Dennis, 63021563418517255630720 isn't a 32-bit number.
Peter Taylor


0

CJam, 37 characters (broken)

"煷➻捬渓类ⶥ땙ዶ꾫㞟姲̷ᐂ㵈禙鰳쥛忩蔃"2G#b[1q~]4G#b%!

Try it online.

How it works

See my new answer.

Example run

$ echo $LANG
en_US.UTF-8
$ base64 -d > flock.cjam <<< IueFt+Keu+aNrOa4k+exu+K2peuVmeGLtuq+q+Oen+Wnsu6AhMy34ZCC47WI56aZ6bCz7KWb5b+p6JSDIjJHI2JbMXF+XTRHI2IlIQ==
$ wc -m flock.cjam
37 flock.cjam
$ cjam flock.cjam < flock.secret; echo
1
$ cjam flock.cjam <<< "1 2 3 4 5"; echo
0

1
737262825 208413108 3974530688 3445680972 2916831257 works but isn't an arithmetic progression. Factored in 3 hours 20 minutes. 512-bit numbers were apparently doable in 72 hours for $75 on EC2 two years ago, so I think that would have been safe.
Peter Taylor

@PeterTaylor: That returns 1, but the last three integers are greater than MAX_INT, so it's not a valid key. That being said, 3 h 20 m is pretty impressive. The algorithm I was using took 16 hours for a 256-bit semiprime...
Dennis

I thought there must be some negative numbers in there somewhere because the deltas were almost right but not quite. I'll get on to it.
Peter Taylor

1
737262825 208413109 -320436607 -849286323 -1378136039
Peter Taylor

@PeterTaylor: That's the one. I hope the 512 bit version lasts longer.
Dennis

-2

C, 212 (Cracked)

This is the same idea as my previous submission, golfed more thoroughly, with a bug corrected that passed 0,0,0,0,0 (Thanks to Dennis for pointing out the bug). Compile with -std=c99.

#define L long long
p(L x){x=abs(x);for(L i=2;i<x;i++){if((x/i)*i==x)return 0;}return(x>1);}
f(a,b,c,d,e){char k[99];L m;sprintf(k,"%d%d%d%d%d",e,d,c,b,a);sscanf(k,"%lld",&m);
return p(a)&p(b)&p(c)&p(d)&p(e)&p(m);}

Any sequence (arithmetic or not) of negative primes will work. Two examples: -7 -37 -67 -97 -127, -157 -127 -97 -67 -37
Dennis

Yeah, my code is just riddled with bugs. The answer nitrous gave is along the lines of what I was looking for. But nice job pointing out the more obvious answers.
Orby
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.