new chapter in article

This commit is contained in:
2026-08-24 14:03:46 +03:00
parent b1806cda5e
commit 548159e5ea
+85
View File
@@ -103,7 +103,88 @@ H_b(R)\subseteq H_b(P).
Для каждого имени вычисляется 32-битный Jenkins one-at-a-time [\Ref{JENKINS}], после чего сохраняются только $b$ младших бит. Пусть $n$ различных имён независимо и равномерно отображаются в пространство из $N=2^b$ значений. Тогда математическое ожидание числа столкнувшихся пар равно
\[
\mathbb{E}C=\binom{n}{2}\frac{1}{2^b}
=\frac{n(n-1)}{2^{b+1}},
\]
а вероятность хотя бы одной коллизии имеет вид
\[
\P(C>0)=1-\prod_{i=0}^{n-1}\left(1-\frac{i}{2^b}\right)
\approx 1-\exp\left(-\frac{n(n-1)}{2^{b+1}}\right).
\]
Эти выражения являются модельными: Jenkins OAAT не является случайным оракулом, поэтому окончательная оценка должна дополняться измерением коллизий на реальном корпусе символов.
Эвристическую верхнюю оценку ложного принятия при $k=|R\setminus P|$ отсутствующих символов можно записать как
\[
\Pr\bigl(H_b(R)\subseteq H_b(P)\mid R\nsubseteq P\bigr)
\lesssim
\left(\frac{|H_b(P)|}{2^b}\right)^k.
\]
Увеличение $b$ снижает вероятность ошибки, но увеличивает кодируемые значения и длину строки. Поэтому выбор \texttt{bpp} представляет собой компромисс между компактностью метаданных и риском коллизий; при формировании \texttt{set:}-строки для \texttt{Requires} набора используется точность, определённая по числу символов соответствующего \texttt{Provides}, а не по обычно намного меньшему числу требований.
\subsection{Кодирование Голомба--Райса}
После сортировки уникальных значений
\[
0\leq x_1<x_2<\dots<x_n<2^b
\]
они заменяются дельтами
\[
\delta_1=x_1,
\qquad
\delta_i=x_i-x_{i-1},\quad i=2,\dots,n.
\]
Для равномерных хешей средний промежуток имеет порядок $2^b/n$, поэтому дельты значительно меньше абсолютных значений и хорошо подходят для кодирования Голомба--Райса [\Ref{GOLOMB-RICE}].
В реализации модуль $M$ равен степени двойки $M=2^m$. Для каждой дельты вычисляются
\[
q_i=\left\lfloor\frac{\delta_i}{M}\right\rfloor,
\qquad
r_i=\delta_i\bmod M.
\]
Частное $q_i$ записывается унарно как $q_i$ нулей и завершающая единица, после которой следуют $m$ младших бит остатка $r_i$. Длина кода одного значения равна
\[
\ell_i=q_i+1+m.
\]
Параметр выбирается приближённо как
\[
m=b-\lfloor\log_2 n\rfloor-1
\]
и ограничивается диапазоном формата $7\leq m\leq31$. При принятой модели суммарная длина битового потока оценивается как
\[
B=\sum_{i=1}^{n}\ell_i
=O\!\left(n\left(1+\log_2\frac{2^b}{n}\right)\right).
\]
\subsection{Base62-представление}
Битовый поток нельзя непосредственно поместить в поле версии RPM: необходима строка из допустимых символов. Исходная реализация использует алфавит \texttt{0--9}, \texttt{a--z}, \texttt{A--Z}. Значения от 0 до 60 записываются обычным символом, а \texttt{Z} служит escape-символом и позволяет представить также шестибитные значения 61, 62 и 63. Их различают два старших бита следующего символа: \texttt{00}, \texttt{01} или \texttt{10}. Комбинация \texttt{11} не используется, поэтому escape-последовательности не могут образовать неоднозначную цепочку. Вследствие этого один символ несёт от пяти до шести бит, и длина текстовой части приближённо пропорциональна $B/6$.
Рассмотрим небольшой пример с $b=10$. Для пяти имён Jenkins OAAT после усечения даёт значения, приведённые в табл.~\Ref{ENCODING_EXAMPLE}.
\begin{table}[H]
\begin{center}
\caption{\label{ENCODING_EXAMPLE}Пример хеширования символов при $b=10$}
\small
\begin{tabular}{|l|r|r|}
\hline
Символ & 32-битный хеш & $h_{10}$ \\
\hline
\texttt{fclose} & \texttt{0x6743def6} & 758 \\
\hline
\texttt{fopen} & \texttt{0x0e984918} & 280 \\
\hline
\texttt{free} & \texttt{0xa5bbbac7} & 711 \\
\hline
\texttt{malloc} & \texttt{0x07c1b8ff} & 255 \\
\hline
\texttt{printf} & \texttt{0xfd1ad5cc} & 460 \\
\hline
\end{tabular}
\end{center}
\end{table}
После сортировки получается массив $(255,280,460,711,758)$, а после вычисления разностей --- $(255,25,180,251,47)$. Для $n=5$ формула даёт $m=7$; полученный 43-битный поток преобразуется в payload \texttt{ZvpACXZy}. Параметрам $b=10$ и $m=7$ соответствуют заголовочные символы \texttt{d} и \texttt{a}, поэтому итоговая строка равна \texttt{set:daZvpACXZy}. Пример показывает, что строка содержит достаточно данных для восстановления упорядоченного множества усечённых хешей, но не исходных имён символов.
\References
\begin{enumerate}
@@ -116,4 +197,8 @@ ALT RPM source code, 2010--2012.
\item
\Label{JENKINS}
\item
\Label{GOLOMB-RICE}
\end{enumerate}