
Author Archives: Tolik Punkoff
N-ART 2018 №1

Крупный вариант по клику
Возобновляем мысленный проект Димы
N-ART
Итак, что такое N-ART, это типа арт-журнал, где типа эксперты выбирают типа произведения искусства для одной цели — опубликовать их на нашем сайте. Критериев отбора всего 2:
1. Нам понравилось
2. Произведение нигде не было опубликовано.
Политика участия. Можно присылать свои работы каким угодно образом, лучше всего по почте или лично, тогда мы их отсканируем (сфотографируем) и отдадим оригинал обратно (вышлем письмом).
Политика редакции. Мы не получаем с публикации денег. Если кто-то из авторов хочет деньги, то он может приписать, что ему нужен донат. Весь донат для автора будет отправлен автору. Мы не берем процентов.
На остальные заебы похуй, весь цифровой контент, попавший к нам распространяется по лицензии Хекса
Сегодня у нас произведение Длиннопанка из города К.
Опечатка по Фрейду

Linux, curl, обнаружение и анализ ошибок HTTP. Улучшаем скрипт.
В первой части я показал, как просто обнаружить ошибки HTTP при работе с curl
. Но на самом деле, подход, использованный в скрипте, немного неправильный:
Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния.
Т.е. объясняя по рабоче-крестьянски, не только код 200 может свидетельствовать об успешном завершении запроса, а другие коды, кроме явных клиентских или серверных ошибок, могут требовать от нас каких-либо действий.
Вообще, коды ответа HTTP разделены на 5 классов:
1xx
— информационные
2xx
— успешное завершение
3xx
— требуется переопределение
4xx
— ошибка, допущенная со стороны клиента
5xx
— ошибка, допущенная со стороны сервера
Вот и модифицируем наш скрипт в соответствии со стандартом.
В общем, надо из кода ответа HTTP извлечь первую цифру, и, соответственно прореагировать. Привожу часть скрипта, ответственного за более подробную реакцию на код ответа HTTP:
curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null EXITCODE=$? if [ $EXITCODE -ne 0 ]; then echo "CURL error $EXITCODE" else HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'` #get HTTP status code HTTPSTATUSMESS=`cat $HEADERDUMP|head -1|cut -d ' ' -f 3- HTTPSTATUSID=`echo $HTTPSTATUS|cut -c 1` #get first char status code case "$HTTPSTATUSID" in 1 ) echo -n "Informational: ";; 2 ) echo -n "Success: ";; 3 ) echo -n "Redirection: ";; 4 ) echo -n "Client Error: ";; 5 ) echo -n "Server Error: ";; * ) echo -n "Unknow status: ";; esac echo "$HTTPSTATUS $HTTPSTATUSMESS" fi
Жирным шрифтом выделена строка, в которой мы получаем этот самый класс кода возврата.
Курсивом — строка, где мы получаем пояснения текстовые пояснения к коду ответа.
Используемая в процессе анализа утилита cut
, в первом случае, позволяет нам вывести в переменную все символы после с третьего пробела.
Перед первым у нас версия протокола http, потом код ошибки, а потом пояснение, которое может содержать несколько пробелов, поэтому awk
тут не подходит.
cut
так же может работать с текстовыми данными, в которых есть разделители, например пробелы, или же с отдельными символами, как в той строке кода, что выделена жирным — так мы можем извлечь первую цифру из кода ответа.
Дальнейший анализ осуществляется с помощью оператора case
Расширенный анализ кодов состояния HTTP:
На Pastebin
На Github
PHP скрипт для проверки:
На Pastebin
На Github
Краткий справочник по командам curl и wget Копия
Утилита cut
Коды статуса HTTP
Оператор case
curl в Linux, ошибка 404, обнаружение и использование кодов ответа HTTP
Итак, возникла следующая задача — определить, когда curl
получил вменяемые данные от http-сервера, а когда нет. В общем, и самом распространенном случае, задача сводится к тому, чтобы определить, отдал ли нам сервер запрашиваемый файл, или отобразил «страница не найдена».
Впрочем, это работает и для других возможных кодов ответа.
Ясно, что сервер, на наш запрос GET
может ответить, как возвратив нам запрашиваемую страницу, так и отправив код, например, 404 (не найдено)
, и возвратив страницу-заглушку для этого случая. Так вот, на уровне скрипта bash или скрипта php необходимо проанализировать ответ сервера, чтобы не выдать пользователю вместо ожидаемых данных, всяческую лабуду. Далее я рассматриваю исключительно консольную Linux-утилиту curl
. Для php, синтаксис, по-моему, отличается.
Есть страница, которую мы хотим получить: http://example.org/page.html
, сохранить ее в файл page.html
и есть curl
, команда будет такая:
curl -o "page.html" http://example.org/page.html
Если страница на месте, то мы получим ее, и ничего анализировать не требуется.
Если же нет, то от большинства web-серверов мы получим страницу-заглушку, например такую, но никакой ошибки при этом.
Как же быть:
Проверяем код ошибки самого curl
, если нет связи с сетью, URL неправильный, или задан неподдерживаемый curl
протокол, если так, то мы получим соответствующий код возврата, наподобие:
curl: (1) Protocol htt not supported or disabled in libcurl
А вот если адрес правильный, и никакой ошибки в адресе или соединении нет, то код возврата не сработает, нам самим придется думать дальше.
Надо получить код ответа HTTP!
Сделать это можно, если получить отдельно заголовки ответа сервера, и после их проанализировать. Благо, для этого никакого страшного колдунства не требуется, достаточно указать утилите curl
опцию -D
(т.е. dump
) и файл, куда выгружать заголовки.
Покажу это на примере конкретного скрипта:
#!/bin/bash HEADERDUMP="/tmp/headerdump.txt" SAVEFILE="/tmp/httpfile" HTTPSTATUS="" curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null EXITCODE=$? if [ $EXITCODE -ne 0 ]; then echo "CURL error $EXITCODE" else HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'` if [ "$HTTPSTATUS" == "200" ];then echo "OK" else echo "HTTP error $HTTPSTATUS" fi fi
заводим 3 переменные
HEADERDUMP="/tmp/headerdump.txt"
— файл, в который будем получать заголовки
SAVEFILE="/tmp/httpfile"
— файл с сервера, который мы хотим получить
HTTPSTATUS=""
— переменная для статуса (состояния) HTTP
curl -o $SAVEFILE $1 -D $HEADERDUM
пытаемся скачать нужный файл (получить страницу):
-o
«имя_файла» — куда сохранять результат
$1
— внутренняя переменная, первый параметр скрипта, при вызове его с командной строки. В своем скрипте надо заменить на свой случай.
можно добавить >/dev/null 2>/dev/null
— для красоты, чтоб не вылезали сообщения о процессе и ошибках.
-D <файл>
— файл, куда будем копировать заголовки
Файл headerdump.txt
выглядит примерно так:
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Fri, 30 Mar 2018 00:17:23 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.33
Link:
Set-Cookie: quick_chat_alias=Anon_240883; path=/
Upgrade: h2,h2c
Vary: Accept-Encoding,User-Agent
В первой строке — интересующая нас информация. Версия протокола (не интересно), код ответа (вот он) и информационное сообщение (не особо надо).
Вычленяем код:
HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`
1. Берем первую строчку (head -1
)
2. Сохраняем в переменную 2-е значение после пробела (разделитель пробел): awk '{print $2}'
Дальше можно анализировать:
if [ "$HTTPSTATUS" == "200" ];then echo "OK" else echo "HTTP error $HTTPSTATUS" fi

Также, впрочем, можно поступить и для анализа запросов POST, вот тестовый скрипт php для отладки подобных возможностей и скрипт bash

Пример с запросом GET
Пример с запросом GET на Гитхаб
Пример с запросом POST
Пример с запросом POST на Гитхаб
Мультик про (анти)копирайт
Точнее про то, что копирайт и копирасты это говно, а копирование — не воровство.
Имеются:
— главный герой, получивший от нас (ваших товарищей из параллельного измерения) Хаопринтер, с возможностью 3D-печати и кучей дополнительных опций. Впрочем, он неплохо работает и с дефолтными настройками.
— злобный и жадный копираст, у которого бомбануло
— судья-взяточник, который, естественно, на стороне копираста
В общем, смотрите 🙂
HTML и CSS мелочи
Абсолютный размер в пикселях
По размеру DIV’а
Пример
Киберфорум
Кот из примера
Еще какие-то
L.S.
Linux. Создание пути со всеми подкаталогами.
Чтобы создать путь со всеми вложенными подкаталогами, достаточно выполнить команду mkdir
с ключом -p
. Например:
mkdir -p ./the/test/path
создаст в текущем каталоге путь the/test/path

Про «Жизнь»
Спрашивают, есть ли что-то подобное в текстовом режиме. Есть, только предупреждаю, там такой говнокодище, что самому смотреть страшно. И некрасиво выглядит, в отличие от графической версии. Если переделаешь, сойдет за зачет, наверное.
Даже картинки не будет.
C# Пример Charmap (таблицы символов) для различных кодировок.

Очередное студенческое задание, да. Причем опять, то ли препод не совсем адекватный, то ли студент, то ли мы дебилы и не видим чего-то лежащего на поверхности. Потому что «совсем для всех» кодировок, поддерживаемых .NET оно не получается.
Для начала, пришлось задачу все-таки глобально поделить на 3 больших части:
— кодировки однобайтовые (Windows 1251, DOS 866 и т.д.)
— кодировка Unicode
— кодировки многобайтовые, но не Unicode (всякие там японские, китайские и прочие).
С ними проще всего. Достаточно перебрать все символы от 0 до 255, перекодировать их последовательно в UTF-16 стандартной функцией класса Encoding
и вывести на экран.
Encoding enc = Encoding.GetEncoding(CP); for (int i = 0; i < 256; i++) { string sChr = enc.GetString(new byte[] { (byte)i }); //... }
Отделить их от остальных тоже просто, у объекта Encoding
есть свойство IsSingleByte
С этим тоже особой сложности нет, весь стандарт открытый, можно взять список диапазонов Юникода прямо с официального сайта. Разобрать, залить в ComboBox
и отображать кусками, для больших кусков сделать постраничное листание.
Главная проблема была побороть глюк с отображением символа с кодом > FFFFh Копия, из-за чего пришлось использовать RichTextBox
и периодически пересчитывать ему размер в зависимости от используемого шрифта и символа, а также в нужных местах перерисовывать таблицу, чтоб та не расползалась.

Вторая проблема - изобрести какое-то подобие "композитных" шрифтов в BabelMap, т.е. подгружать разные шрифты для разных диапазонов Unicode, поскольку шрифта, абсолютно поддерживающего все символы Unicode нет, он бы получился чудовищно большим. И те, которые есть-то, не маленькие, из нескольких файлов, и весят под сотню мегабайт.
Чтоб ради задания не загадить систему шрифтами, пришлось предусмотреть возможность грузить их из файлов, а тут поджидал уже другой глюк, на этот раз Framework'а Копия.
В общем, процентов 90 кода (да и процессорного времени) уходит на возню со шрифтами и отрисовку таблицы.
Отделить варианты кодирования Unicode от других кодовых страниц тоже несложно, благо всего этих вариантов не так много (UTF16 LE/BE, UTF32 LE/BE, UTF8 и UTF7).
public static bool IsUnicode(int CodePage) { if (CodePage == 65001 || CodePage == 65000 || CodePage == 1201 || CodePage == 1200 || CodePage == 12000 || CodePage == 12001) return true; else return false; }
А получить конкретный символ можно вот таким способом:
if ((num >= 0x00d800) && (num <= 0x00dfff)) { st = Convert.ToString((char)num); } else { st = char.ConvertFromUtf32(num); }
if ((num >= 0x00d800) && (num <= 0x00dfff))
- это чтобы не попасть в диапазоны суррогатов, но все-таки на их месте что-то отображать (в шрифтах там обычно пустые символы или знаки ?), а char.ConvertFromUtf32()
при попадании в диапазон суррогатов свалится с ошибкой.
А вот тут уже так легко не получится, все-таки единственный вменяемый способ, это искать спецификации на каждую. Поэтому, в рамках задания, эта часть задачи была признана некорректной и не решаемой.
Нет, был, конечно, вариант простого перебора всех возможных вариантов. Максимальное количество байт, необходимых для кодирования символа в указанной кодировке можно получить с помощью Encoding.GetEncoding(cp).GetMaxByteCount(1)
, но перебрать все возможные значения, например, для массива размером уже в 4 байта, перебирая его, например, так, да еще и фильтруя все лишнее, непомерно долго.
В общем, вроде бы того, что сделали, оказалось достаточно.
Пришлось студенту писать пояснительную записку с источниками 🙂
Исходник примера на GitHub
Скачать
Leha S, NKT
C# Ошибка «Попытка чтения или записи в защищенную память» при работе со шрифтами из PrivateFontCollection
Понадобилось грузить TTF-шрифты из файлов, что делается с помощью PrivateFontCollection.AddFontFile(FileName)
. И, внезапно, стал проявляться плавающий глюк, возникающий, если периодически пересоздавать объект PrivateFontCollection
. Например, при попытке сделать MeasureString(Text, LoadedFont).ToSize()
, программа стала вываливаться с ошибкой "Попытка чтения или записи в защищенную память"
.
Пишут, что это глюк Framework’а и толковое решение только одно, создавать PrivateFontCollection
один раз при запуске программы, например, в каком-нибудь статическом классе, и больше ее не трогать. Т.е. подгружать новые шрифты можно, а пересоздавать коллекцию не надо.
Минус решения — можно загадить память подгружаемыми шрифтами, если подгрузить много файлов. Но лучше пока ничего не нашел.
В принципе, можно создать вот такой статический класс, который будет подгружать шрифт в коллекцию, и хранить в Dictionary
сопоставление между именем файла и шрифтом в коллекции. Если файл еще не был загружен — подгружать, если был, возвращать позицию в коллекции.
Ну и чтоб два раза не вставать, класс FileFont, который заодно меняет параметры шрифта (размер и начертание).
На Cyberforum’е тоже пока ничего более дельного не предложили.
C# Отображение суррогатной пары (символа с кодом >FFFF)
Известно, что внутренний формат строк в .NET — UTF16, что значит, что символы из основной многоязыковой плоскости (BMP) Unicode, т.е. с кодом меньше FFFF кодируются одним машинным словом, а остальные символы — двумя, одно из которых т.н. суррогат.
Так вот, как оказалось, с отображением суррогатных пар может возникнуть проблема. Контролы Windows Forms могут воспринимать символ с кодом >FFFF не как один символ, как должно быть, а как два. Для примера пробуем отобразить анатолийский иероглиф

с кодом 0x14476

Как видно, TextBox
и Label
воспринимают символ, как два символа, и, соответственно, его не отображают, а RichTextBox
видит, что это один символ, но не отображает его, даже при правильно заданном шрифте.
MessageBox
также отображает символ не как один, а как два:

Для устранения проблемы с RichTextBox
достаточно задать нужный шрифт перед тем, как присвоить свойству Text
нужные символы.
int Code = 0x14476; //анатолийский иероглиф Font AnFont = new Font("Anatolian", 24, FontStyle.Regular, GraphicsUnit.Pixel, 1); private void Form1_Load(object sender, EventArgs e) { string strSP = char.ConvertFromUtf32(Code); lblTest.Font = AnFont; txtTest.Font = AnFont; lblFont.Text = AnFont.FontFamily.Name; rtbTest.Font = AnFont; lblTest.Text = strSP; txtTest.Text = strSP; rtbTest.Text = strSP; }

PictureBox
также отрисовывает нужный символ без проблем:

А корень проблемы кроется не в C#, .NET и компонентах Windows Forms, а в самой Windows. Пакет обновления SP1 для Windows 7 решает проблему полностью.
Наиболее универсальным решением является использование RichTextBox
для работы с такими символами, во всяком случае, это работает даже для Windows XP, для которой ждать патчей, понятное дело, не приходится.
Главное, не забывать про то, что шрифт надо задавать до вставки/присвоения символа.
Шрифты поддерживающие весь Unicode-диапазон
Или, во всяком случае, большинство символов.
TWBh: шрифт, поддерживающий большинство символов Unicode
Дополнительно:
Композитный шрифт для BabelMap (TWBhBabelCompositeFont.xml)
Композитный шрифт для WPF (TWBh.CompositeFont)
Композитный шрифт для примера простой Charmap для Unicode и однобайтных кодировок (babel.cf)
Universalia самый распространенный максимально поддерживающий Unicode набор шрифтов Ссылка Magnet
Набор шрифтов с почти полной поддержкой Unicode, собранный неизвестным пользователем интернета Что и как поддердживает каждый файл шрифта, есть описание в тектовом файле. Плюс есть композитный шрифт для тестовой программы.
Программа BabelMap Копия
Самый совершенный Charmap для Unicode, поддерживает композитные шрифты и все диапазоны Unicode
#FreeBakholdin
За кадром.
Или будни редакции.
Главред все переживал, не выглядит ли он на «свои почти 40 лет» и не сильно ли у него «насекомная (рептильная) мордочка», несмотря на все-таки серьезность акции и вполне ответственное, как наше всехное, так и его личное отношение. Не смог побороть глупую улыбку в камеру, как мы его просили.
«Ну не могу я, когда фоткают, не улыбаться, даже на загран 7 раз фотографировали», сказал редактор.
-А как ты, сишарпер хренов, по скайпу выступаешь.
-У меня камера хреновая, там хрен чо хрен разглядишь. И сишарп вообще не гадание на Таро, там лицо видеть не обязательно.
Ктулху с ним, как получилось, так и ладно.
БрокаЦентр
Нашли еще две темы. По-моему круто! Хотя мечтаю познакомить вас с их первым альбомом, на котором вполне себе панковский гражданско-оборонно-гаражный звук. Надеюсь, архивы Леши не оскудели, и в ближайшее время, таки да.
БрокаЦентр — СОН
БрокаЦентр — Терпи, ведь это любовь
Вторая песня, это заодно запоздалое поздравление с 8 марта всем парням, которым достались курицы или еще какие зверюшки, вместо женщин. Потому что их с 8 марта поздравлять и надо на самом деле. Такие тян, действительно, не нужны. Но многие парни, к сожалению, тетерева и фазаны, хотя думают, что львы.
Как-то так. Удачи!
BrokaCenter — INSIDE
Ну раз уж у нас сегодня вечер панковско-рокерских воспоминаний, навеянный приездом Леши, сегодняшним содержимым ленты, и вообще, каким-то анархическим настроением, то вот вам еще немного кондопожского панка.
Группа БрокаЦентр была в Кондопоге самой долгоиграющей, если исключить пипец какую древнюю группу «Всё» и Германа Фирсова, который вообще один из первых и старейших рок-музыкантов Карелии, России и СССР.
Больше БЦ на нас в нежном возрасте (включая половину ОИМ, и всю российскую часть редакции), наверное повлияли только LovinGod и группа Purgen.
Это одна из последних известных записей. Попробуем найти все и выложить в сеть. Даже введу новый тег.
Гаражный панк
Репетиция кондопожской группы «Позитив», 200█ год. Эх, как все было круто и мило, и отрываться можно было до утра, благо бешеный принтер еще не был настолько бешеным. Ну и Леше отдельное с кисточкой, хз в каких архивах откопавшему запись.
ГЕОРГИЕВСКАЯ ЧЛЕНТОЧКА
Уберите от экрана женщин, беременных детей и обязательно покажите ватникам!
Это меня так замечательно поздравили с 23 февраля. Такой вот дерьмоядреной бiмбой, способной порвать гигаватное количество пердаков!
Алсо, у нас была георгиевская туаленточка, она менее натуралистичная, но не менее разжигающая.
C# Перевод чисел между системами счисления стандартной функцией класса Convert
Да, совсем забыл выложить исходник, спасибо, что напомнили.
Перевести число в/из десятичной в 2, 8, и 16-ричную систему можно с помощью стандартной функции класса Convert
Convert.ToInt64(s, From)
s
— строка, содержащая число.
From
— основание системы счисления.
Обратное преобразование:
Convert.ToString(n, To)
n
— число
To
— основание системы счисления.
На выходе будет строка
В примере еще показал, как ограничить ввод в текстовое поле, чтоб можно было вводить только определенные символы, и добавил отображение символа по его коду (в однобайтной кодировке, для Unicode будет погода на Марсе). Числа можно вводить через пробел.
