madf: (Default)
У OpenSSL багато критиків, і уже багато форків. Раніше мені якось не доводилось стикатися з цією бібліотекою, але останній рік я працюю з нею майже щоденно, точніше з криптографічною її частиною. Тож є кілька думок з цього приводу.
1. У OpenSSL офігенна архітектура у тому що стосується криптографії (EVP_-stuff, BIO_-stuff).
2. У OpenSSL гівняна документація. Точніше у них дофіга документації на функції, але майже немає прикладів їх використання. Доводиться багато гуглити і шукати по stackoverflow про те як саме користуватись їх функціями.
3. У роботі з OpenSSL варто мати версію зібрану зі зневаджувальною інформацією і не треба боятися лізти у джерельні коди — там усе більш-менш доступно.
4. Варто розуміти як саме працює RSA і алгоритми на еліптичних кривих. Так, наприклад, я тільки вчора узнав що цифровий підпис зроблений за допомогою ECDSA кожного разу різний для одно і того ж набору даних. Причина у тому що у процесі підпису один із параметрів обирається випадково і саме його випадковість захищає від підбору приватного ключа за підписом. Існує RFC 6979 який описує алгоритм обирання цього параметру для детермінованого підпису, але він наразі не імплементований у OpenSSL. Це суттєво зменшує можливості до тестування коду що працює з ECDSA.
5. Варто знати що таке ASN.1 і як з ним працювати. Наприклад, я тільки сьогодні узнав що DER вимагає мінімально можливого кодування цілих чисел, і тому підпис може мати різний розмір — у мене він коливався від 69 до 72 байт для SHA256 digest і кривої prime256v1. При чому EVP_DigestVerifyFinal повертав коректну довжину підпису тільки після фактичного підпису.
6. У OpenSSL погано з повідомленнями про помилки. Фактично, жодне з тих що я отримав мені не допомогло.
madf: (Default)
Я досить часто зустрічаю думку що для написання безпечного з точки зору memory management коду на C++ треба його „обмазати“ std::shared_ptr. Мене ця точка зору дико бісить, бо насправді std::shared_ptr означає що у програміста просто не залишилось іншого виходу. std::shared_ptr дуже складна і доволі небезпечна штука, тому я вважаю що для використання саме цього smart pointer треба чітко розуміти його природу, призначення і вміти відповідати на наступні запитання:


Junior level:

  • Що таке std::smart_ptr?

  • Для чого він потрібен?

  • Які відносини між std::shared_ptr і std::weak_ptr?

  • Навіщо потрібен std::weak_ptr?

  • Чи можна вважати std::weak_ptr smart pointer?

  • Чи можна вважати std::weak_ptr вказівником?

  • Що ж тоді таке std::weak_ptr?



Middle level:

  • Що таке std::enable_shared_from_this?

  • Для чого він потрібен?

  • Як std::enable_shared_from_this взаємодіє з наслідуванням?



Senior/Lead/Architect level:
  • PIMPL і std::enable_shared_from_this — як їх помирити?


Насправді, у 80% випадків достатньо value/reference/std::unique_ptr. До речі, raw pointer, про який кажуть шо його ніколи-ніколи, навіть під дулом автомату не можна використовувати насправді можна використовувати для імітації maybe-семантики (коли std::/boost::optional з якихось причин не підходить). Нічого страшного у ньому немає. Треба просто запам'ятати кілька правил:


  1. Ссилка і вказівник не передають володіння (за винятком new, але від нього треба відмовлятись на користь std::make_shared/std::make_unique). Нам не треба хвилюватись про знищення ресурсу.

  2. Значення робить копію або передає володіння (якщо повертаємо локальний об'єкт із функції). Нам не треба хвилюватись про знищення ресурсу.

  3. std::unique_ptr передає володіння. Знищення ресурсу на нашій совісті (але std::unique_ptr потурбується про це).



Я стверджую що слідування цим правилам ніколи не призводить до проблем з пам'яттю і покриває 80% випадків, коли треба обирати вид smart pointer. Для 20% що залишились все ж доводиться використовувати std::shared_ptr. Один із таких випадків — Boost.ASIO. std::shared_ptr у цьому випадку не потрібен тоді і тільки тоді коли ваші об'єкти гарантовано живуть довше за boost::asio::io_service.

Overdesign

Dec. 31st, 2015 10:29 am
madf: (Default)
Скільки програмістів потрібно щоб замінити лампочкуСкільки LOC потрібно щоб на OpenSSL звмутити base64?

std::string base64(const std::string& value)
{
    BIO* bio = BIO_new(BIO_f_base64());
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    BIO_push(bio, BIO_new(BIO_s_mem()));
    BIO_write(bio, value.c_str(), value.size());
    BIO_flush(bio);
 
    std::string res;
    char* data = nullptr;
    size_t size = BIO_get_mem_data(bio, &data);
    if (size != 0 && data != nullptr)
        res.assign(data, size);
 
    BIO_free_all(bio);
 
    return res;
}


Насправді більше, бо треба ж перевіряти виділення пам'яті...
madf: (Default)
Хоч я і великий прихильник git, за наочністю представлення дерева гілок Mercurial дасть йому 100 очок фори. На роботі Mercurial, і у нашому гігабайтному репозиторію з купою офіційних і власних гілок я зовсім не плутаюсь. На власних скромних проектах уже сам біс ногу зломить розібрати де яка гілка росте.
madf: (Default)
Якщо ви у своїй програмі запровадили кеш — готуйтесь відгрібати.
Якщо ви запровадили кеш у розподіленій системі — ви вже двічі відгребли авансом.

Перевірено досвідом. На роботі в одному місці був 2-рівневий кеш який, нібито, мав прискорювати доступ до даних. Я просто прибрав цей кеш і тим самим прискорив роботу програми щонайменше у 10 разів.
madf: (Default)
Я завжди знав що тема часових поясів у програмуванні — це пекельні котли і авгієві конюшні (разом з темою локалізації), тому старався уникати її. Коли знайомі адміни дорікали мені за логи у UTC я казав що Грінвіч рулить (не коньяк) і взагалі у логах які скачуть туди-сюди двічі на рік фіг що знайдеш потім. Плюс там всякі політичні складові — переходити, чи не переходити... Тож уникав я цієї теми довго, поки не стикнувся з податковою службою Грузії. Не вдаючись у подробиці, знадобилось на одному проекті зафігачити кастомні часові пояси для перегляду певної статистики. Ржака в тому, що українські користувачі взагалі не скаржилися на час у UTC (відношення було приблизно таке: „лишь были б желуди, ведь я от них жирею“), російські користувачі трохи скаржились що треба перераховувати локальний час щоб подивитись статистику за добу, а грузини покликали на поміч своїх податківців і категорично відмовились щось там рахувати. Ну в принципі, позиція правильна. Я теж завжди кажу що це задача комп’ютера щось там рахувати — він для того створений був.
Read more... )
madf: (Default)
C++ Ranges are Pure Monadic Goodness
Bartosz як завжди прекрасний. Якщо у 17-й стандарт додадуть ranges від Eric Niebler то з C++ уже можна буде жити у сучасному світі. А то там всякі додають optional без fmap з семантикою вказівників і думають що несуть світло й добро...

C++14

Aug. 18th, 2014 09:55 pm
madf: (Default)
Затвердили стандарт: „We have C++14!“.
madf: (Default)
Уявіть собі що у вас є контейнер вказівників на базовий клас і цей контейнер треба відсортувати за типами конкретних об’єктів що лежать у контейнері. Щоб було більше конкретно, живий приклад: маємо журнал виконання певної операції (у моєму випадку то були corporate actions: stock split, merger і spin-off, але це не важливо), треба цю операцію „відкотити“, але порядок виконання операцій при „відкочуванні“ важливий, а записи у журналі можуть іти у довільному порядку.
Проблема у написанні оператора порівняння двох об’єктів за вказівниками (або посиланнями) на базовий клас. Проблема відома під назвою „мультиметоди“ чи „подвійна диспетчеризація“. У C++ зазвичай вирішується або через матрицю відношень, або через dynamic_cast, або через (щасругнусь) паттерн „Visitor“. Але фігачити таблиці порівнянь ліниво, тому використаємо template metaprogramming voodoo щоб заставити компілятор нагенерувати то все самому.
Годі базікати, вйо до коду!
Read more... )
madf: (Default)
Майєрс смалить.

Originally posted by [livejournal.com profile] thedeemon at Scott Meyers o C++
Абсолютно волшебное выступление Мейерса о современном С++, как много там косяков и ненужных сложностей прямо со входа:
http://www.ustream.tv/recorded/47947981
Практически stand-up comedy получилась. Рекомендую.
madf: (Default)
fix
Ерік кльовий чувак, але від цього коду у мене моск в трубочку скручується.
Власне, звідси: „F-Algebras and C++“. У Бартоша на Haskell набагато простіше виходить: „Understanding F-Algebras“.
madf: (Default)
Випадково помітив:
POSIX Shell   C++98/03   C++11   Haskell

#!/bin/sh

for i in {1..4}
do
    echo $i
done
      

 
#include <iostream>

int main()
{
int arr[] = {1, 2, 3, 4};
for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
std::cout << arr[i] << "\n";
return 0;
}
_Winnie C++ Colorizer

 
#include <iostream>

int main()
{
for (auto i : {1, 2, 3, 4})
std::cout << i << "\n";
return 0;
}
_Winnie C++ Colorizer

 
module Main where

main = mapM_ print [1..4]
      

6 LOC   9 LOC   8 LOC   3 LOC

Для чого це потрібно? Іноді буває необхідно проітеруватись по enumeration. Не городити ж для цього масив, в кінці кінців...
PS: ага, і Shell, і плюсовий код теж можна в один рядок записати. Але ж читабельність...
madf: (Default)
Що б там не казав Bjarne Stroustrup шановному [livejournal.com profile] ivan_gandhi, Bartosz Milewski з оптимізмом дивиться у майбутнє: http://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/
Добро перемагає!
madf: (Default)
Сьогодні раптово виявив що у хаскелевій System.Directory немає функції переміщення файлу. Є тільки перейменування.
Різниця суттєва: неможливо перейменувати файл так що нове розташування знаходиться на іншому фізичному пристрої. Помилка приблизно така:

rename: unsupported operation (Invalid cross-device link)

Вихід, звісно, простий:

moveFile :: FilePath -> FilePath -> IO()
moveFile source dest = copyFile source dest >> removeFile source
madf: (Default)
... до тих пір поки я не дібрався до столу і не жмакнув по клавіаутрі десктопа і ноута.
Десктоп, як виявилось взагалі намертво завис вночі під час оновлення системи. А на ноуті... Там я побачив приблизно 7500 непрочитаних листів у одному своєму поштовому аккаунті і трохи більше 3000 у іншому. Шок! Всі листи пусті, без теми і відправника.
Поки я їх видаляв — помітив що кількість невпинно росте. Приблизно 1-2 листа на секунду. Винуватим, як згодом виявилось, був kdepim. Я його полагодив пару місяців тому, відкрутивши MySQL (хоча його рекомендують самі розробники) і прикрутивши PostgreSQL. А вчора після оновлення кед він знову зламався і тепер серить мені у скриньку пустими листами. Шо ж мені так з поштою нещастить...
При чому буквально пару днів тому товариш мій теж оновив кеди і у нього virtuoso (хто не в курсі — це така велосипедна СУБД для Nepomuk) зохавав усе вільне місце своїми логами. Відповідний баг датовано 2011-м роком: https://bugs.kde.org/show_bug.cgi?id=264465
А тим часом сотні тисяч людей пишуть усяке лайно для апсторів і гуглоплеїв. Я сам якось, повертаючись з роботи, чув розмову двох парубків: вони на повному серйозі обговорювали перспективи заробітку з продаж чергової версії тетрису для андроїда.

А, да, ще про пошту. Я собі якось купив ще один VPS, підняв там домени, пошту і все таке, шоби переїхати із корпорації добра, але ніде її не світив ще. Цього тижня туди прилетів перший спам лист. Як?!
madf: (Default)
Тут шановний [livejournal.com profile] sharpc лякає людей синтаксисом C++, а мені згадались два баги компілятора (а точніше реалізації стандартної бібліотеки), на які ми на роботі наштовхнулись буквально минулого тижня.
Кому не страшно — зазирніть під кат )

Вирву із контексту: „... мир окончательно разделится на людей, которые успели выучить C++, пока он еще был простым, и на тех, кто никогда не осилит...“.
madf: (Default)
Ось вам, звуки знайомі мені з дитинства:

ZX Spectrum був саморобний, татко з мамою робили. Телевізор чорно-білий, а магнітофон, звісно, зовнішній. І блок живлення частково зовнішній, бо вбудований швидко згорів. Ззовні був трансформатор, діодний міст і конденсатор, а всередині залишився стабілізатор.
Саме на такій штуці я писав свої програмки і грав у ігри.
У платі явно була тріщина, бо якщо сильно стукнути — він зависав. Reset було виведено на клавіатуру, приблизно туди де зараз Caps Lock. Але я часто його ненароком натискав (особливо після того як цілу годину вводив з папірця програму), тому було зроблено „запобіжник“ — для того щоб Reset спрацював потрібно було одночасно натиснути дві кнопки.
Більшість касет належала сестрі, тому свої програми я, переважно, записував на листочок, і коли треба — набирав наново :) А частіше просто писав щось нове прямо з голови. У ZX Basic було погано з рекурсією (точніше її взагалі не було), тому багато кльових штук із тих що я робив у школі на повноцінному 80286 з Basic від Microsoft я відтворити тут не міг.

Profile

madf: (Default)
madf

April 2018

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 18th, 2025 01:18 am
Powered by Dreamwidth Studios