- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
(define rsagen
(lambda ()
(for-each (lambda (rsa counter)
(cond
((> (random) 0.5)
(fprintf out-quest "%N=~s, d=~s\n\\item Задача. Криптосистема RSA. Дано: $p=~s,\\ q=~s,\\ e=~s$. Вычислить $N, d$.\n"
(third rsa)
(fifth rsa)
(first rsa)
(second rsa)
(fourth rsa)
))
(else
((lambda (randM)
(fprintf out-quest "%p=~s,q=~s,e=~s,M=~s\n\\item Задача. Криптосистема RSA. Дано: $d=~s,\\ N=~s,\\ C=~s$. Вычислить $M$.\n"
(first rsa)
(second rsa)
(fourth rsa)
(rsacrypt randM (fourth rsa) (third rsa))
(fifth rsa)
(third rsa)
randM
))
((Y
(lambda (checkrand)
(lambda (randf)
((lambda (rand)
(cond
((not (eq? (rsacrypt rand (fourth rsa) (third rsa)) rand))
rand)
(else
(checkrand randf))))
(randf)))))
(lambda () (- (third rsa) (+ (random (quotient (third rsa) 2)) 1))))
)
)
)
)
(take (shuffle (getalllistallmany_e (next-primes 7 50) (next-primes 5 10))) 14)
(build-list 14 (lambda (x) (+ x 1))))
))
Генерирование заданий по криптосистеме RSA. Обратите внимание на Y комбинатор.
говно в умах, а не в языке
Проще надо быть, проще.
Y-комбинатор - это такая могучая хрень, удовлетворяющая уравнению
Y f = f (Y f)
(типа неподвижная точка), которая позволяет выражать рекурсию для безымянных функций.
Однако создатели Scheme не были настолько суровыми извращенцами, чтоба запретить давать функциям имена. Кроме того, там можно иметь вложенные определения функций. Поэтому причина появления Y-комбинатора в явном виде довольно таинственна. Возможно, автору кода жмёт череп.
Y - не сдандартная функция лиспа (собственно, стандартных лиспов есть всего один - ANSI Lisp, Common Lisp в большой степени старается следовать этому стандарту, но практически любая реализация добавляет кучу своего собственного помимо стандарта).
Если очень просто, то Y по отношению к функции, как
(JavaScript)
по отношению к объекту. Т.е. такая специальная конструкция, которая вызывает рекурсивно другую функцию (обычно передавая вызываемую функцию параметром ей же самой - за счет чего выполняемая функция перестает быть сама по себе рекурсивной, а рекурсию нужно обрабатывать только для Y, это делает вычисления для компиляторов функциональных языков более простыми).
lisp без макросов - как водка без пива
Что p и q - простые числа (они же публичный, приватный ключи, e - функция Эйлера=(p-1)*(q-1), M - степень)
rand - нужен для генерации случайных простых p и q, но код тут приведен неполностью - неясно что там считает next-primes
Правда где тут говно мне непонятно.
Одно могу сказать точно - 5 10; 7 50 - слишком малые числа для серъезного RSA. И потому оно пахнет лабой.
http://ideone.com/tZBxr
Вложить defun в другой defun не получится, нужен flet или labels.
В Scheme всё немного проще и логичнее:
define определяет символ в локальном скопе и во внешний скоп определение не попадает. Разумеется, можно использовать define внутри определения функции для определения вспомогательных функций.
http://ideone.com/0FVc5
Разница есть и она ощутима, хоть и не принципиальна. На мой взгляд, подход Scheme более интуитивен и красив.
Да, конструкция позволительна, я ошибся, ideone.com сбил с толку.
http://ideone.com/GYk9d
Мне CL нравиться больше из-за своей практичности. Просто в Scheme некоторые вещи сделаны более красиво и удобно.
Надо так:
http://ideone.com/4UON7
В CL есть defun, определённый обычно в терминах, зависящих от реализации. Во что он превращается, можно посмотреть в самой лисп-системе.
http://ideone.com/45nZ9