- 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
- 45
- 46
- 47
static void generatorPass()
{
string letters = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ1234567890";
StringBuilder initPass = new StringBuilder("", 6);
for (int i = 0; i < 6; i++)
{
initPass.Append(0);
}
int count = 0;
for (int i = 0; i < 6; i++)
{
for (int a = 0; a < letters.Length; a++)
{
initPass[i] = letters[a];
for (int b = 0; b < letters.Length; b++)
{
initPass[i + 1] = letters[b];
for (int c = 0; c < letters.Length; c++)
{
initPass[i + 2] = letters[c];
for (int d = 0; d < letters.Length; d++)
{
initPass[i + 3] = letters[d];
for (int e = 0; e < letters.Length; e++)
{
initPass[i + 4] = letters[e];
for (int f = 0; f < letters.Length; f++)
{
initPass[i + 5] = letters[f];
Console.WriteLine(count++ + "]----> Проверяется пароль: [" + initPass.ToString() + "]");
}
}
}
}
}
}
}
}
Кажется, что то пошло не так . Как можно сделать это проще ?
1. Все пермутации строки из одного символа - список содержащий данную строку.
2. Все пермутации строки из N символов - пермутации строки из N-1 символов где перед каждым символом добавлен N-ный символ из исходной строки + этот же символ добавлен в конце.
Можно, только это не пермутации, а декартово возведение в степень.
Всё равно геммор, нужно же n раз заджоинить, врядли в одно строчку получится. Я даже в хаски в одну не могу... Две надо.
Вот что лямбда-зонд животворящий делает
> интуитивный и выразительный язык
Только для осиляторов
я просто дальше туториала и пошел потому что фокус языка/этц мне не подходил. erlang мне намного привлекательней.
> кококо
Скажи что он не нужен.
въебал минус
Erlang is shit, SHIT!
компилятор сожрёт даже сладкий хлеб, и принесёт его на тарелочке в рантайм
пирфоманс
records-хуекордс
guards -- говно
отсутствие чистоты
типичная архитектура -- спагетти из кучи процессов, ожидающих невесть что, невесть откуда
нельзя инфиксные операторы определять, а значит хуй вам, а не управление control flow
VM, которой чуть-чуть не хватает проца -- обречённая VM
строки
иерархических модулей не завезли
ебанатский синтаксис
sequence $ replicate n alphabet
Спасибо.
монады в моем сишарпике
http://melpon.org/wandbox/permlink/VXUNyy9R4lBf5sek
По сути, надо чтобы функция в качестве аргумента принимала указатель того же типа, что и та сама функция, а такое рекурсивное определение типа в Си нельзя делать
Или может еще нужны какие-то извраты с memcpy или union?
мне кажется memcpy + сырая память должно быть легальным, хотя не уверен
правда даже если так можно, выглядит как то малоюзабельно
http://stackoverflow.com/a/12358902 на стековерфлоу именно так и объясняют
Так что кто знает, где ещё можно столкнуться с far-указателями.
хотя теоретически на какой-то говноплатформе может быть call far запрещен
> 36-битные указатели и адресовать 64 гига памяти вместо четырёх.
а как это реализоано в тулчейне? 64битными становятся указательки и оттуда выдергивается сегмент?
В регистрах CS, DS, ES, FS, GS хранится селектор (16-битное значение). Селектор — это номер записи в таблице селекторов. Запись содержит базовый адрес сегмента и лимит (в обычном режиме они 32-разрядные, в PAE имеют большую длину).
Чтобы получить far-указатель, нужно указать и селектор, и смещение, итого на 32-битной машине 16+32 бит = 48 бит. Т. е. far-указатель — это фактически запись с двумя полями.
near-указатель можно скастить в far, добавив к нему значение селектора текущего сегмента. В Винде обычно CS=DS, потому что используется «плоская» модель памяти, но в окружении с сегментированной моделью памяти селектор текущего сегмента кода и селектор сегмента данных могут не совпадать (более того, одна программа может использовать несколько сегментов), поэтому преобразование будет зависеть от контекста.
Наоборот же far в near можно преобразовать только в том случае, если селектор, записанный в far-указатель, совпал селектором «текущего» контекста. В общем случае преобразование far в near невозможно. Это как у плавающего питуха порядок отрезать.
https://en.wikipedia.org/wiki/Physical_Address_Extension
https://ru.wikipedia.org/wiki/Дескрипторные_таблицы
Чтобы набить ГК ключевыми словами и сюда пришли 15 троллей-ассемблерщиков.
> Указатель всегда фар, либо чтоб юзать указатель надо юзать пару селектор:смещение?
В известных реализациях были атрибуты. В Watcom C было void __far *, void __near * и void __huge *. Слово __huge использовалось только в 16-битном компиляторе и только для массивов, использующих более одного сегмента. Было ещё слово __far16, позволяющее из 32-битного кода поставить указатель на 16-битный сегмент.
Наконец, были ещё «based pointers» — когда указатель хранился как near, но в декларации был указан сегмент, так что компилятор при использовании подставлял нужный сегмент. Пример:
В самом iptr хранится только смещение, как в near-указателе, но при использовании в сегментный регистр подставится адрес секции _CODE экзешника.
Был ещё атрибут типа __seg для недоуказателя, в котором можно было хранить только селектор.
В Борманд Си и в MSVC были аналогичные атрибуты (только у MS знаков подчёркивания было поменьше).
А ещё был оператор :> для склеивания сегмента со смещением в один указатель. Обычно использовался не напрямую, а посредством макроса:
Но самое страшное, что __FAR и __NEAR — это макросы, которые в бессегментной модели памяти flat определены как пустое значение, чтобы код, написанный под сегментированную модель, компилировался без доработки.
А потом придёт ещё 1 и на ГК снова не будет троллей-ассемблерщиков.
---
а хотя да, и проблемы нет. Просто надо вместо void** указатель на функцию сделать.
с точки зрения гарвардской рахитектуры и сишки может.
Раз мы void(*)(void) юзаем вместо func*, то
например int (*)(int, func* recArg) записываем как int (*)(int, void(*recArg)(void)). Размеры там одинаковые, а перед вызовом arg мы все равно скастим к верной сигнатуре int (*)(int, func*), а именно к int (*)(int, void(*)(void)).
С точки зрения стандарта это может и лажа, но уб не бомбанет.
Стандартный Паскаль совместим с гарвардской моделью, а Object Pascal (Turbo Pascal, Delphi, FPC etc) нет.
Почему? В стандартном Паскале тип указатель (включая pointer, который является аналогом сишного void *) мог указывать только на данные. Функцию можно было передавать в функцию, но с этим аргументом нельзя было ничего делать, кроме вызова. Пример:
То есть вроде как и можно было сослаться на функцию (мы сослались на sin), но поместить её адрес в переменную типа pointer нельзя. И нельзя объявить переменную, указывающую на функцию, хотя параметр функции, указывающий на функцию, объявить можно (в данном случае мы объявили F). Данный и код надёжно разделены, враг не пройдёт.
А как сделано в Object Pascal? Ключевое слово function/procedure у параметра функции теперь использовать нельзя, но его можно использовать в декларации типа.
Мы сделали тайпдеф и у нас F можно использовать как любую переменную. Мы можем значение параметра F скопировать в «несемантический» указатель типа pointer и наоборот:
Pointer может хранить и указатели на данные, и указатели на код. Совместимость с гарвардской архитектурой в Object Pascal утеряна.
Довольно логично иметь UB в случае каста указателя на функцию void foo(int) к указателю на функцию int bar(const char*) с последующим вызовом последней.
Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)
В коде по ссылке - там вообще даже не указатель на функцию, а void**. Т.е. компилятор вправе форматнуть Ц, если захочет.
http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
Так что позиксу срать на сишные стандарты
Конечно. Си же кроссплатформенный, а позикс только на никсах.
В коде по ссылке там void** - дважды указатель на void - но вот тут
от него отнимаем 1 и он единожды разыменовывается, в итоге получается просто void*
который потом тут
Кастуется в указатель на функцию, принимающую char **, void ** и возвращающую int. Ну и потом я это дело вызываю с аргументами arr_ptr-1,func_ptr-1 Так что в функцию я кастую не void** а void*
В одну строчку не сделать.
Тоже в одну строчку.
https://ru.wikipedia.org/wiki/Гипероператор
https://ru.wikipedia.org/wiki/Быстрорастущая_иерархия
Сходу такие варианты:
1. Рекурсивный вызов функции.
2. Редукция до одного цикла. Общий счётчик, из которого частичные счётчики получаются делением с остатком (если диапазоны фиксированы и известны).
Что ещё можно придумать?
И ещё вопрос. Бывают циклы высших порядков?
Ну и перевод на конечный автомат никто не отменял. Yield это просто сахарок для этого.
O(len*len2) вместо O(len2^len).
Сделать какую-нибудь компайл-тайм питушню, которая принимает массив интервалов для каждого счётчика и массив блоков кода / функций, которые будут выполняться на каждой итерации... и потом всё это будет раскрываться хитрым способом в цикл высшего порядка.
Хуйня этот ваш "доступ к \"AST\"", надо чтоб гомоиконность. Вот в D честно признались https://govnokod.ru/27615#comment664409 что им нехватает гомоиконности как в LISP. Признались ли в этом разрабы "Nim"?
В случае с трансформацией AST тебе надо заучивать в какую AST ноду превращается каждый элемент синтаксиса.