В C++11 добавили char16_t, char32_t и u16string, u32string как альтернативу «непонятно чему» wchar_t и wstring, а также <codecvt> в целом и codecvt_utf8 в частности для конвертации, включая суррогатные пары.
Ну почему же никто? Из самого масштабного — www.yosefk.com/c++fqa. Просто в мире C++ в ответ на такие статьи выходят новые версии языка, а не ответные статьи в стиле «в языке этого нет, поэтому вам это не нужно».
Здесь мы имеем дело с вызовом функции «getenv», результат которой не используется и даже не записывается в переменную. Вот как описана эта функция на сайте cplusplus.com.
Retrieves a C-string containing the value of the environment variable whose name is specified as argument. If the requested variable is not part of the environment list, the function returns a null pointer.
Использование «getenv» в таком виде бессмысленно и только смущает при чтении кода.
In a program that uses the wmain function, _wenviron is initialized at program startup according to settings taken from the operating-system environment. [...] Similarly, in a program that uses wmain, _environ is initially NULL because the environment is composed of wide-character strings. On the first call to _getenv or _putenv, a corresponding multibyte-character string environment is created and is pointed to by _environ.
Чтобы из W-версии wmain использовать A-версию _environ, как раз и нужен A-вызов getenv, возвращаемое значение которого можно выбросить.
Общее соображение: brotli совершенно явно затачивался на текстовые данные. Естественно, тест от Google содержит исключительно тексты. (Интересно, кстати, что PPMd, который на текстах рвёт LZMA по качеству сжатия, в сравнении даже не упомянут — хотя 7-Zip, который там упомянут, его вполне реализует.)
2nd order context modeling
В deflate дерево Хаффмана фиксировано в пределах блока. В английском языке самые частые буквы — 'e' и 't', а 'h' замыкает первую десятку; deflate отразит это короткими кодами для 'e' и 't' и кодом подлиннее для 'h'. Однако, если последняя прочитанная буква — 't', то вероятность получить следующей букву 'h' резко повышается, и вот это deflate не способен осознать при кодировании литералов (конечно, артикль «the», начиная со второго вхождения, будет заменён на ссылку назад… но этого мало).
С русским языком с учётом UTF-8 всё ещё хуже — алгоритмы сжатия оперируют байтами, а не символами. В строке D0 A5 D0 B0 D0 B1 D1 80 D0 B0 D1 85 D0 B0 D0 B1 D1 80 deflate смешает в одну кучу D0/D1 и 80/Bx и будет плохо сжимать и то, и другое. Статистика для 'Ё' (D0 81) и 'с' (D1 81) смешивается, и так далее.
brotli может иметь несколько деревьев Хаффмана в одном блоке и при кодировании/декодировании байта смотрит на два предыдущих байта. Для текста это сильно помогает.
re-use of entropy codes
Формат позволяет иметь несколько наборов деревьев Хаффмана и дёшево переключаться между ними. «Язык» текста, «язык» HTML-тегов, «язык» скриптов на HTML-странице, «язык» inline CSS имеют довольно разные свойства. deflate придётся либо смешивать всё это, либо при переключении каждый раз заново выписывать дерево.
larger memory window of past data
Это аргумент исключительно супротив deflate с его максимальным LZ77-окном в 32K. В том же LZMA можно выставить окно чуть ли не до гигабайта. (Окно в данном контексте — максимально возможный диапазон для ссылок назад, фрагмент исходного файла, в котором упаковщик ищет переиспользуемые последовательности байт и который должен держать в памяти распаковщик. deflate, на минуточку, создавался в те времена, когда 640K хватало всем.)
joint distribution codes
Особенность кодирования. В deflate, грубо говоря, две базовых команды — «запиши литерал» (значение, непосредственно закодированное в команде) и «скопируй последовательность байт такой-то длины с таким-то смещением назад». Литералы и длины подвешены на одном и том же дереве Хаффмана; распаковщик читает код из этого дерева, если значение <256, это литерал, если >256, это ссылка (ровно 256 — конец блока). В brotli одна базовая команда — «запиши столько-то литералов, они закодированы дальше, и потом скопируй последовательность байт такой-то длины с таким-то смещением назад». При этом литералы висят на своём собственном дереве, а на дереве длин расположены пары из длины цепочки литералов и длины ссылки назад (поэтому «joint distribution»). В отличие от предыдущих пунктов, априори неочевидно, насколько это полезно и полезно ли вообще (если длины на самом деле независимы, улучшения не будет, а дерево сильно раздуется), но раз его включили, то какой-то выигрыш, наверное, есть.
Если так, то первая пустая клетка будет выпадать всегда более вероятно, чем последняя. Например, при постановке второго шарика числа 0 и 80 приведут к первой пустой клетке, что сделает её в два раза более вероятной, чем любую другую (к которой приведёт только одно число).
Так Wireshark и tshark — разные интерфейсы к одному и тому же. tshark -Y ssl.handshake.type==1 -T fields -e ssl.handshake.extensions_server_name -i {interface}
В этот раз пойдем немного другим путем и будем начинать не с точки входа, а с того места, где встречается сигнатура $HSS. Идем в Search -> Text… (или нажимаем Alt+T), вводим $HSS, ставим галку Find all occurences и… ничего не находим. Думаем немного и понимаем, что у нас LittleEndian-машина, и $HSS при загрузке в регистр будет выглядеть как SSH$ или 53534824h. Ищем этот вариант и вуаля, одно вхождение:
Так делать не стоит. Search -> Text… — это поиск в дизассемблированном листинге. Если соответствующую часть кода IDA по какой-то причине оставила в виде дампа db (например, процедура вызывается косвенно типа call dword ptr [eax+14h]), или если (условно) следующая версия IDA начнёт превращать такие константы в текст «cmp dword ptr [ebx], 'SSH$'», ничего не найдётся.
Лучше Search -> sequence of bytes..., оно понимает задание строки типа "$HSS" в кавычках.
Самое неправильное — это использование хэша вместо массива. Асимптотика, конечно, у них обоих O(1), но константы очень сильно разные.
По мелочи:
— вычёркивание, начинающееся с 3 * i, теряет кучу времени, повторяя заведомо уже вычеркнутое до i * i,
— после того, как i достигнет корня из N, операция |= вообще молотит вхолостую.
import array
def eratosthenes(N):
# nonsimp[j] corresponds to 2j+1
simp, nonsimp = [2], array.array('b', [0 for i in xrange((N + 1) // 2)])
i = 3
while i * i <= N:
if not nonsimp[(i - 1) // 2]:
for j in xrange((i * i - 1) // 2, (N + 1) // 2, i):
nonsimp[j] = 1
simp.append(i)
i += 2
simp.extend([2 * j + 1 for j in xrange((i - 1) // 2, (N + 1) // 2) if not nonsimp[j]])
return simp
print(len(eratosthenes(11 * 10 ** 6)))
До 10^9 интервалов >= 256 три штуки:
436273009..436273291: 282
649580171..649580447: 276
944192807..944193067: 260
Этот комментарий спонсирован PARI/GP, на котором это вычисляется в одну строчку за 20 секунд (из которых предвычисление таблицы занимает 4). default(primelimit,10^9);q=0;forprime(p=2,10^9,if(p-q>=256,print(q," .. ",p,": ",p-q));q=p)
var
XPos,YPos:integer;
Field:array[1..9,1..9] of integer;
CurColor:shortint;
Colors:array[1..3] of integer;
NumBalls,NumFreeFields:integer;
procedure GenerateNextBall(index:integer);
var
i:integer;
pos:word;
begin
pos := Random(80);
repeat
XPos := (pos mod 9) + 1;
YPos := (pos div 9) + 1;
if Field[XPos,YPos] <> 0 then
begin
inc(pos);
if pos = 81 then
pos := 0;
end;
until Field[XPos,YPos] = 0;
CurColor := Colors[index];
Field[XPos,YPos] := CurColor;
for i := 1 to 3 do
begin
{draw ball of size i and delay}
end;
inc(NumBalls);
dec(NumFreeFields);
end;
Статья находится в хабе «Математика». Непосредственная практическая применимость… хм, за доказательство гипотезы обещают дать миллион долларов, сойдёт?
<codecvt>
в целом и codecvt_utf8 в частности для конвертации, включая суррогатные пары.Это не так. msdn.microsoft.com/ru-ru/library/windows/desktop/stxk41x1%28v=vs.80%29.aspx:
Чтобы из W-версии wmain использовать A-версию _environ, как раз и нужен A-вызов getenv, возвращаемое значение которого можно выбросить.
В deflate дерево Хаффмана фиксировано в пределах блока. В английском языке самые частые буквы — 'e' и 't', а 'h' замыкает первую десятку; deflate отразит это короткими кодами для 'e' и 't' и кодом подлиннее для 'h'. Однако, если последняя прочитанная буква — 't', то вероятность получить следующей букву 'h' резко повышается, и вот это deflate не способен осознать при кодировании литералов (конечно, артикль «the», начиная со второго вхождения, будет заменён на ссылку назад… но этого мало).
С русским языком с учётом UTF-8 всё ещё хуже — алгоритмы сжатия оперируют байтами, а не символами. В строке D0 A5 D0 B0 D0 B1 D1 80 D0 B0 D1 85 D0 B0 D0 B1 D1 80 deflate смешает в одну кучу D0/D1 и 80/Bx и будет плохо сжимать и то, и другое. Статистика для 'Ё' (D0 81) и 'с' (D1 81) смешивается, и так далее.
brotli может иметь несколько деревьев Хаффмана в одном блоке и при кодировании/декодировании байта смотрит на два предыдущих байта. Для текста это сильно помогает.
Формат позволяет иметь несколько наборов деревьев Хаффмана и дёшево переключаться между ними. «Язык» текста, «язык» HTML-тегов, «язык» скриптов на HTML-странице, «язык» inline CSS имеют довольно разные свойства. deflate придётся либо смешивать всё это, либо при переключении каждый раз заново выписывать дерево.
Это аргумент исключительно супротив deflate с его максимальным LZ77-окном в 32K. В том же LZMA можно выставить окно чуть ли не до гигабайта. (Окно в данном контексте — максимально возможный диапазон для ссылок назад, фрагмент исходного файла, в котором упаковщик ищет переиспользуемые последовательности байт и который должен держать в памяти распаковщик. deflate, на минуточку, создавался в те времена, когда 640K хватало всем.)
Особенность кодирования. В deflate, грубо говоря, две базовых команды — «запиши литерал» (значение, непосредственно закодированное в команде) и «скопируй последовательность байт такой-то длины с таким-то смещением назад». Литералы и длины подвешены на одном и том же дереве Хаффмана; распаковщик читает код из этого дерева, если значение <256, это литерал, если >256, это ссылка (ровно 256 — конец блока). В brotli одна базовая команда — «запиши столько-то литералов, они закодированы дальше, и потом скопируй последовательность байт такой-то длины с таким-то смещением назад». При этом литералы висят на своём собственном дереве, а на дереве длин расположены пары из длины цепочки литералов и длины ссылки назад (поэтому «joint distribution»). В отличие от предыдущих пунктов, априори неочевидно, насколько это полезно и полезно ли вообще (если длины на самом деле независимы, улучшения не будет, а дерево сильно раздуется), но раз его включили, то какой-то выигрыш, наверное, есть.
#define _SECURE_SCL 0
перед включением всех заголовков. Или возьмите VS поновее.geektimes.ru/post/243195
Почитайте про приоритеты операций.
*i_ptr++
означаетi_ptr++
.tshark -Y ssl.handshake.type==1 -T fields -e ssl.handshake.extensions_server_name -i {interface}
Так делать не стоит. Search -> Text… — это поиск в дизассемблированном листинге. Если соответствующую часть кода IDA по какой-то причине оставила в виде дампа db (например, процедура вызывается косвенно типа call dword ptr [eax+14h]), или если (условно) следующая версия IDA начнёт превращать такие константы в текст «cmp dword ptr [ebx], 'SSH$'», ничего не найдётся.
Лучше Search -> sequence of bytes..., оно понимает задание строки типа "$HSS" в кавычках.
А покажите версию после оптимизаций, интересно.
По мелочи:
— вычёркивание, начинающееся с
3 * i
, теряет кучу времени, повторяя заведомо уже вычеркнутое доi * i
,— после того, как
i
достигнет корня изN
, операция|=
вообще молотит вхолостую.436273009..436273291: 282
649580171..649580447: 276
944192807..944193067: 260
Этот комментарий спонсирован PARI/GP, на котором это вычисляется в одну строчку за 20 секунд (из которых предвычисление таблицы занимает 4).
default(primelimit,10^9);q=0;forprime(p=2,10^9,if(p-q>=256,print(q," .. ",p,": ",p-q));q=p)