Вы находитесь на странице: 1из 19

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ

ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего
образования
«Тихоокеанский государственный университет»

Математические методы защиты информации и компьютерной безопасности

Лабораторная работа №2
“Арифметическое кодирование”

Текстовый документ по лабораторной работе


по дисциплине «Теория кодирования, сжатия и восстановления информации»

Выполнил студент Л. Д. Гааз


КБ(c)-01

Проверила Е. В. Карачанская

Хабаровск – 2023 г.
Цель: рассмотреть кодирование информации методом арифметического
кодирования и адаптивным методом кодирования.
Ход выполнения работы
Вариант – 2
Кодируемый текст: "скажи-ка, дядя, ведь"
Код программы, реализующий кодирование информации методом
арифметического кодирования, на языке программирования Python:
from decimal import Decimal as D, ROUND_HALF_UP
from math import ceil, log

# Функция для подсчета вероятностей символов в тексте


def get_intervals(text):
# Создаем словарь для хранения частот символов
frequencies = {}
for char in text:
if char in frequencies:
frequencies[char] += 1
else:
frequencies[char] = 1

# Создаем словарь для хранения вероятностей символов


# Рассчитываем вероятности символов в тексте
probabilities = {char: D(frequencies[char] /
len(text)).quantize(D('1.00000'), ROUND_HALF_UP) for char in
frequencies}

# Создаем интервалы для каждого символа на основе вероятностей


intervals = {}
prob_sum = 0
for char in probabilities.keys():
# Определяем интервалы для символов
intervals[char] = [prob_sum, prob_sum + D(frequencies[char] /
len(text)).quantize(D('1.00000'), ROUND_HALF_UP)]
prob_sum += D(frequencies[char] / len(text)).quantize(D('1.00000'),
ROUND_HALF_UP)

# Устанавливаем правую границу последнего интервала в 1


intervals[list(intervals.keys())[-1]][1] = D('1')

return intervals

# Функция для кодирования текста методом арифметического кодирования


def arithmetic_encoding(text):
# Получаем интервалы для символов в тексте
intervals = get_intervals(text)
# Вывод интервалов для каждого символа
for char in intervals:
print(f'{char}: [{str(intervals[char][0])}, {str(intervals[char]
[1])})')

# Инициализируем нижнюю и верхнюю границы интервала [0, 1)


lower = D('0')
upper = D('1')
i = 1
# Проходим по каждому символу в тексте для кодирования
for char in text:
length = upper - lower
# Обновляем верхнюю и нижнюю границы на основе интервалов символов
upper = D(lower + length * intervals[char][1]).normalize()
lower = D(lower + length * intervals[char][0]).normalize()
# Вывод интервалов на каждой итерации
print(f'{i}:[{str(lower)}, {str(upper)})')
i += 1

return [lower, upper]

text = "скажи-ка, дядя, ведь"


code = arithmetic_encoding(text)
print(f"Текст: {text}")

# Вывод полученного кодового интервала


print(f"Кодовый интервал: [{str(code[0])}, {str(code[1])})")

# Вывод кода, который является средним значением кодового интервала


print(f"Код: {(code[0] + code[1]) / 2}")

# Расчет количества бит, необходимых для представления сообщения


z = D((code[0] + code[1]) / 2).as_integer_ratio()[1]
print(f'Сообщение можно закодировать с помощью {ceil(log(z, 2))} бит')

Результат:
Кодируемый текст: " скажи-ка, дядя, ведь "
Код программы, реализующий кодирование информации адаптивным
алгоритмом арифметического кодирования, на языке программирования
Python:
from decimal import Decimal as D, ROUND_HALF_UP
from math import ceil, log

# Функция для подсчета вероятностей символов в тексте


def get_intervals(weights):
# Рассчитываем вероятности для каждого символа на основе их весов
probabilities = {}
for char in weights:
probabilities[char] = D(weights[char] /
sum(weights.values())).quantize(D('1.00000'), ROUND_HALF_UP)

# Создаем интервалы для каждого символа на основе вероятностей


intervals = {}
prob_sum = 0
for char in probabilities.keys():
# Определяем интервалы для символов
intervals[char] = [prob_sum, prob_sum + D(weights[char] /
sum(weights.values())).quantize(D('1.00000'),

ROUND_HALF_UP).normalize()]
prob_sum += D(weights[char] /
sum(weights.values())).quantize(D('1.00000'), ROUND_HALF_UP).normalize()

# Устанавливаем правую границу последнего интервала в 1


intervals[list(intervals.keys())[-1]][1] = D('1')

return intervals

# Функция для кодирования текста методом адаптивного арифметического


кодирования
def adaptive_arithmetic_encoding(text):
# Инициализируем нижнюю и верхнюю границы интервала [0, 1)
lower = 0
upper = 1
weights = {char: 1 for char in text} # Изначально все символы имеют
одинаковый вес (1)
print(weights)

for char in text:


# Получаем интервалы на основе текущих весов символов
intervals = get_intervals(weights)
for ch in intervals:
print(f'{ch}: [{str(intervals[ch][0])}, {str(intervals[ch]
[1])})')
# Вычисляем длину текущего интервала
length = upper - lower
# Обновляем верхнюю и нижнюю границы интервала в соответствии с
текущим символом
upper = D(lower + length * intervals[char][1]).normalize()
lower = D(lower + length * intervals[char][0]).normalize()
# Увеличиваем вес текущего символа
weights[char] += 1
# Выводим текущий интервал и веса после обновления
print(f'[{lower}, {upper})')
print('-----------------------------------------------------')
print(weights)

return [lower, upper]

# Тестируем функцию
text = "скажи-ка, дядя, ведь"
code = adaptive_arithmetic_encoding(text)
print(f"Текст: {text}")
# Вывод полученного кодового интервала
print(f"Кодовый интервал: [{str(code[0])}, {str(code[1])})")
# Вывод кода, который является средним значением кодового интервала
print(f"Код: {(code[0] + code[1]) / 2}")
# Расчет количества бит, необходимых для представления сообщения
z = D((code[0] + code[1]) / 2).as_integer_ratio()[1]
print(f'Сообщение можно закодировать с помощью {ceil(log(z, 2))} бит')

Результат:

Далее я вставлю что получил из программы ввиде текста.


"C:\Users\RAY\PycharmProjects\лала 3\venv\Scripts\python.exe"
C:/Users/RAY/PycharmProjects/pythonProject2/22.py

{'с': 1, 'к': 1, 'а': 1, 'ж': 1, 'и': 1, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.07692)

к: [0.07692, 0.15384)

а: [0.15384, 0.23076)

ж: [0.23076, 0.30768)

и: [0.30768, 0.38460)

-: [0.38460, 0.46152)

,: [0.46152, 0.53844)

: [0.53844, 0.61536)

д: [0.61536, 0.69228)

я: [0.69228, 0.76920)

в: [0.76920, 0.84612)

е: [0.84612, 0.92304)

ь: [0.92304, 1)

[0, 0.07692)

-----------------------------------------------------

{'с': 2, 'к': 1, 'а': 1, 'ж': 1, 'и': 1, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.14286)

к: [0.14286, 0.21429)

а: [0.21429, 0.28572)

ж: [0.28572, 0.35715)

и: [0.35715, 0.42858)

-: [0.42858, 0.50001)
,: [0.50001, 0.57144)

: [0.57144, 0.64287)

д: [0.64287, 0.71430)

я: [0.71430, 0.78573)

в: [0.78573, 0.85716)

е: [0.85716, 0.92859)

ь: [0.92859, 1)

[0.0109887912, 0.0164831868)

-----------------------------------------------------

{'с': 2, 'к': 2, 'а': 1, 'ж': 1, 'и': 1, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.13333)

к: [0.13333, 0.26666)

а: [0.26666, 0.33333)

ж: [0.33333, 0.40000)

и: [0.40000, 0.46667)

-: [0.46667, 0.53334)

,: [0.53334, 0.60001)

: [0.60001, 0.66668)

д: [0.66668, 0.73335)

я: [0.73335, 0.80002)

в: [0.80002, 0.86669)

е: [0.86669, 0.93336)

ь: [0.93336, 1)

[0.012453926730696, 0.012820238085348)

-----------------------------------------------------
{'с': 2, 'к': 2, 'а': 2, 'ж': 1, 'и': 1, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.125)

к: [0.125, 0.250)

а: [0.250, 0.375)

ж: [0.375, 0.4375)

и: [0.4375, 0.5000)

-: [0.5000, 0.5625)

,: [0.5625, 0.6250)

: [0.6250, 0.6875)

д: [0.6875, 0.7500)

я: [0.7500, 0.8125)

в: [0.8125, 0.8750)

е: [0.8750, 0.9375)

ь: [0.9375, 1)

[0.0125912934886905, 0.01261418794835625)

-----------------------------------------------------

{'с': 2, 'к': 2, 'а': 2, 'ж': 2, 'и': 1, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.11765)

к: [0.11765, 0.23530)

а: [0.23530, 0.35295)

ж: [0.35295, 0.47060)

и: [0.47060, 0.52942)

-: [0.52942, 0.58824)

,: [0.58824, 0.64706)

: [0.64706, 0.70588)
д: [0.70588, 0.76470)

я: [0.76470, 0.82352)

в: [0.82352, 0.88234)

е: [0.88234, 0.94116)

ь: [0.94116, 1)

[0.01260206762140920195, 0.012603414273526741365)

-----------------------------------------------------

{'с': 2, 'к': 2, 'а': 2, 'ж': 2, 'и': 2, '-': 1, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.11111)

к: [0.11111, 0.22222)

а: [0.22222, 0.33333)

ж: [0.33333, 0.44444)

и: [0.44444, 0.55555)

-: [0.55555, 0.61111)

,: [0.61111, 0.66667)

: [0.66667, 0.72223)

д: [0.72223, 0.77779)

я: [0.77779, 0.83335)

в: [0.83335, 0.88891)

е: [0.88891, 0.94447)

ь: [0.94447, 1)

[0.01260281575399310097200325, 0.01260289057398475146190065)

-----------------------------------------------------

{'с': 2, 'к': 2, 'а': 2, 'ж': 2, 'и': 2, '-': 2, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.10526)
к: [0.10526, 0.21052)

а: [0.21052, 0.31578)

ж: [0.31578, 0.42104)

и: [0.42104, 0.52630)

-: [0.52630, 0.63156)

,: [0.63156, 0.68419)

: [0.68419, 0.73682)

д: [0.73682, 0.78945)

я: [0.78945, 0.84208)

в: [0.84208, 0.89471)

е: [0.89471, 0.94734)

ь: [0.94734, 1)

[0.01260282362954542210256985032, 0.01260283150509774323313645065)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 2, 'ж': 2, 'и': 2, '-': 2, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.1)

к: [0.1, 0.25)

а: [0.25, 0.35)

ж: [0.35, 0.45)

и: [0.45, 0.55)

-: [0.55, 0.65)

,: [0.65, 0.70)

: [0.70, 0.75)

д: [0.75, 0.80)

я: [0.80, 0.85)
в: [0.85, 0.90)

е: [0.90, 0.95)

ь: [0.95, 1)

[0.0126028255984335023852115004, 0.01260282638598873449826816044)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 1, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.09524)

к: [0.09524, 0.23810)

а: [0.23810, 0.38096)

ж: [0.38096, 0.47620)

и: [0.47620, 0.57144)

-: [0.57144, 0.66668)

,: [0.66668, 0.71430)

: [0.71430, 0.76192)

д: [0.76192, 0.80954)

я: [0.80954, 0.85716)

в: [0.85716, 0.90478)

е: [0.90478, 0.95240)

ь: [0.95240, 1)

[0.01260282612348082453034411452, 0.01260282616098420468356787267)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 1, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.09091)

к: [0.09091, 0.22727)

а: [0.22727, 0.36363)
ж: [0.36363, 0.45454)

и: [0.45454, 0.54545)

-: [0.54545, 0.63636)

,: [0.63636, 0.72727)

: [0.72727, 0.77272)

д: [0.77272, 0.81817)

я: [0.81817, 0.86362)

в: [0.86362, 0.90907)

е: [0.90907, 0.95452)

ь: [0.95452, 1)

[0.01260282615075590781437915711, 0.01260282615246043644234317692)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 2, 'д': 1, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.08696)

к: [0.08696, 0.21739)

а: [0.21739, 0.34782)

ж: [0.34782, 0.43478)

и: [0.43478, 0.52174)

-: [0.52174, 0.60870)

,: [0.60870, 0.69566)

: [0.69566, 0.78262)

д: [0.78262, 0.82610)

я: [0.82610, 0.86958)

в: [0.86958, 0.91306)

е: [0.91306, 0.95654)
ь: [0.95654, 1)

[0.01260282615208990600919635829, 0.01260282615216401891394023388)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 2, 'д': 2, 'я': 1, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.08333)

к: [0.08333, 0.20833)

а: [0.20833, 0.33333)

ж: [0.33333, 0.41666)

и: [0.41666, 0.49999)

-: [0.49999, 0.58332)

,: [0.58332, 0.66665)

: [0.66665, 0.74998)

д: [0.74998, 0.83331)

я: [0.83331, 0.87498)

в: [0.87498, 0.91665)

е: [0.91665, 0.95832)

ь: [0.95832, 1)

[0.01260282615215166503384847726, 0.01260282615215475331858915455)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 2, 'д': 2, 'я': 2, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.08)

к: [0.08, 0.20)

а: [0.20, 0.32)

ж: [0.32, 0.40)

и: [0.40, 0.48)
-: [0.48, 0.56)

,: [0.56, 0.64)

: [0.64, 0.72)

д: [0.72, 0.80)

я: [0.80, 0.88)

в: [0.88, 0.92)

е: [0.92, 0.96)

ь: [0.96, 1)

[0.01260282615215388859886176491, 0.01260282615215413566164101909)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 2, 'д': 3, 'я': 2, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.07692)

к: [0.07692, 0.19230)

а: [0.19230, 0.30768)

ж: [0.30768, 0.38460)

и: [0.38460, 0.46152)

-: [0.46152, 0.53844)

,: [0.53844, 0.61536)

: [0.61536, 0.69228)

д: [0.69228, 0.80766)

я: [0.80766, 0.88458)

в: [0.88458, 0.92304)

е: [0.92304, 0.96150)

ь: [0.96150, 1)

[0.01260282615215408814158605734, 0.01260282615215410714565503757)
-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 2, ' ': 2, 'д': 3, 'я': 3, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.07407)

к: [0.07407, 0.18518)

а: [0.18518, 0.29629)

ж: [0.29629, 0.37036)

и: [0.37036, 0.44443)

-: [0.44443, 0.51850)

,: [0.51850, 0.59257)

: [0.59257, 0.66664)

д: [0.66664, 0.77775)

я: [0.77775, 0.88886)

в: [0.88886, 0.92590)

е: [0.92590, 0.96294)

ь: [0.96294, 1)

[0.01260282615215409799519582359, 0.01260282615215409940282721295)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 2, 'д': 3, 'я': 3, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.07143)

к: [0.07143, 0.17857)

а: [0.17857, 0.28571)

ж: [0.28571, 0.35714)

и: [0.35714, 0.42857)

-: [0.42857, 0.50000)

,: [0.50000, 0.60714)
: [0.60714, 0.67857)

д: [0.67857, 0.78571)

я: [0.78571, 0.89285)

в: [0.89285, 0.92856)

е: [0.92856, 0.96427)

ь: [0.96427, 1)

[0.01260282615215409884982514533, 0.01260282615215409895037225547)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 3, 'д': 3, 'я': 3, 'в': 1, 'е': 1, 'ь': 1}

с: [0, 0.06897)

к: [0.06897, 0.17242)

а: [0.17242, 0.27587)

ж: [0.27587, 0.34484)

и: [0.34484, 0.41381)

-: [0.41381, 0.48278)

,: [0.48278, 0.58623)

: [0.58623, 0.68968)

д: [0.68968, 0.79313)

я: [0.79313, 0.89658)

в: [0.89658, 0.93106)

е: [0.93106, 0.96554)

ь: [0.96554, 1)

[0.01260282615215409893997367334, 0.0126028261521540989434405377)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 3, 'д': 3, 'я': 3, 'в': 2, 'е': 1, 'ь': 1}
с: [0, 0.06667)

к: [0.06667, 0.16667)

а: [0.16667, 0.26667)

ж: [0.26667, 0.33334)

и: [0.33334, 0.40001)

-: [0.40001, 0.46668)

,: [0.46668, 0.56668)

: [0.56668, 0.66668)

д: [0.66668, 0.76668)

я: [0.76668, 0.86668)

в: [0.86668, 0.93335)

е: [0.93335, 0.96668)

ь: [0.96668, 1)

[0.01260282615215409894320947119, 0.01260282615215409894332502178)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 3, 'д': 3, 'я': 3, 'в': 2, 'е': 2, 'ь': 1}

с: [0, 0.06452)

к: [0.06452, 0.16129)

а: [0.16129, 0.25806)

ж: [0.25806, 0.32258)

и: [0.32258, 0.38710)

-: [0.38710, 0.45162)

,: [0.45162, 0.54839)

: [0.54839, 0.64516)

д: [0.64516, 0.74193)
я: [0.74193, 0.83870)

в: [0.83870, 0.90322)

е: [0.90322, 0.96774)

ь: [0.96774, 1)

[0.01260282615215409894328401981, 0.01260282615215409894329520164)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 3, 'д': 4, 'я': 3, 'в': 2, 'е': 2, 'ь': 1}

с: [0, 0.0625)

к: [0.0625, 0.15625)

а: [0.15625, 0.25000)

ж: [0.25000, 0.31250)

и: [0.31250, 0.37500)

-: [0.37500, 0.43750)

,: [0.43750, 0.53125)

: [0.53125, 0.62500)

д: [0.62500, 0.75000)

я: [0.75000, 0.84375)

в: [0.84375, 0.90625)

е: [0.90625, 0.96875)

ь: [0.96875, 1)

[0.01260282615215409894329485221, 0.01260282615215409894329520164)

-----------------------------------------------------

{'с': 2, 'к': 3, 'а': 3, 'ж': 2, 'и': 2, '-': 2, ',': 3, ' ': 3, 'д': 4, 'я': 3, 'в': 2, 'е': 2, 'ь': 2}

Текст: скажи-ка, дядя, ведь


Кодовый интервал: [0.01260282615215409894329485221,
0.01260282615215409894329520164)

Код: 0.01260282615215409894329502692

Сообщение можно закодировать с помощью 95 бит


Вывод: в ходе данной лабораторной работы было рассмотрено
кодирование информации методом арифметического кодирования и
адаптивным методом кодирования.

Вам также может понравиться