Скачиваний:
0
Добавлен:
18.09.2026
Размер:
27 Кб
Скачать

МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ,

СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»

(СПбГУТ)

ФАКУЛЬТЕТ ИНФОКОММУНИКАЦИОННЫХ СЕТЕЙ И СИСТЕМ (ИКСС)

КАФЕДРА ЗАЩИЩЕННЫХ СИСТЕМ СВЯЗИ (ЗСС)

______________________________________________________________________________

Отчет

по лабораторной работе №2

«Нахождения наибольшего общего делителя НОД()»

Выполнили: студенты группы ИБС-32

Проверил:

доцент кафедры ЗСС к.т.н Кушнир Д.В.

Теоретическая часть

  1. Нахождения наибольшего общего делителя НОД().

В криптографии важную роль играет теория чисел.

Некоторые задачи из теории чисел, используемые при построении криптографических преобразований:

I. Нахождение наибольшего общего делителя чисел a и b: НОД(a,b).

  1. Один из путей решения – разложить каждое из чисел на множители и найти в двух разложениях максимальный совпадающий, однако такой подход является неэффективным (имеет экспоненциальную сложность).

  1. Алгоритм Эвклида – нахождение НОД.

Алгоритм в общем виде: Найти: НОД(a,b) a  =b     *q1    + r1 0≤ri<b //q1-целое,r1-остаток от деления a на b * b  =r1    *q2    + r2 0≤r2<r1 ………………………………

rn-3=rn-2 *qn-1 +rn-1 rn-2=rn-1 *qn +0 rn=0 Ответ: НОД(a,b)=rn-1 //ответ – последний ненулевой остаток.

* Примечание: в выражении a=b  *q1 + r1 имеется ввиду, что производится деление числа а на b и вычисляется остаток r1 и количество целых q1.

Пример НОД(1234,54) 1234 = 54 *22 +46   54 = 46 * 1 + 8   46 =  8 * 5 + 6   8 =  6 * 1 + 2   6 =  2 * 3 + 0 Последний ненулевой остаток 2, т.е. НОД (1234,54)=2

Формализованное описание алгоритма Эвклида:

Алгоритм НОД(a,b) a>b

Начальные присвоения A=a; R=B=b;

В цикле выполняем:

a) R=остаток от деления A на B; 

IF(R=0) B – ответ

b) A=B;

c) B=R;

Пример НОД(24;15)

A

B

q

R

24

15

24

=

15

*

1

+

9

15

=

9

*

1

+

6

9

=

6

*

1

+

3

6

=

3

*

2

+

0

Бинарный алгоритм Евклида 

Бинарный алгоритм Евклида вычисления НОД оказывается более быстрым при реализации этого алгоритма на компьютере, поскольку использует двоичное представление чисел а и b. 

Бинарный алгоритм Евклида основан на следующих свойствах наибольшего общего делителя (считаем, что 0 < b ≤ а): 

  1. если оба числа а и b четные, то НОД(a,b) = 2 · НОД(a/2 , b/2)

  2. если число а нечетное, число b четное, то НОД(a, b) = НОД(а, b/2); 

  3. если оба числа а и b нечетные, а > b, то НОД(а, b) = НОД(а – b, b); 

  4. если а = b, то НОД(а, b) = а. 

Формализованное описание алгоритма Бинарного алгоритма Евклида. 

Вход: Целые числа a, b; 0 < b ≤ а. 

Выход. d = HOД(a,b).

  1. Положить g ← 1.

  2. Пока оба числа а и b четные, выполнять а← a/2 , b ← b/2, g ← 2g до получения хотя бы одного нечетного значения а или b. 

  3. Положить u ← a, v ← b. 

  4. Пока u ≠ 0, выполнять следующие действия. 

4.1. Пока u четное, полагать u ← u/2. 

     4.2. Пока v четное, полагать v ← v/2. 

4.3. При u ≥ v положить: u ← u–v, в противном случае: v ← v–u. 

  1. Положить d ← gv. 

  1. Результат: d. Р 

Пример («ручное» вычисление): НОД(88,52)

НОД(88,52) = 2*НОД(44,26) = 4*НОД(22,13) = 4*НОД(11,13) = 

= 4*НОД(13-11,11) = 4*НОД(2,11)  = 4*НОД(11-2,2) = 4*НОД(9,2) =

= 4*НОД(9-2,2) = 4*НОД(7,2) = 4*НОД(5,2) = 4*НОД(5-2,2) = 4*НОД(3,2) =

= 4*НОД(3-2,2) = 4*НОД(1,2) = 4*НОД(2-1,1)=4*НОД(1,1)=4

Решение

3 вариант:

Задание 1.

A = 26 B = 44

44 = 26*1 + 18

26 = 18*1 + 8

18 = 8*2 + 2

8 = 2*4 + 0

НОД = 2

Задание 2.

def gcd_euclid(a, b): while b: quotient = a // b remainder = a % b print(f"{a} = {b} * {quotient} + {remainder}") a, b = b, remainder print(f"НОД: {a}") return a a = int(input("Введите первое число: ")) b = int(input("Введите второе число: ")) gcd_euclid(a, b)

Введите первое число: 1111492

Введите второе число: 564422

1111492 = 564422 * 1 + 547070

564422 = 547070 * 1 + 17352

547070 = 17352 * 31 + 9158

17352 = 9158 * 1 + 8194

9158 = 8194 * 1 + 964

8194 = 964 * 8 + 482

964 = 482 * 2 + 0

НОД: 482

Задание 3.

НОД(44,26) = 2*НОД(22,13) = 2*НОД(11,13) = 

= 2*НОД(13-11,11) = 2*НОД(2,11)  = 2*НОД(11-2,2) = 2*НОД(9,2) =

= 2*НОД(9-2,2) = 2*НОД(7,2) = 2*НОД(5,2) = 2*НОД(5-2,2) = 2*НОД(3,2) =2*НОД(3-2,2) = 2*НОД(1,2) = 2*НОД(2-1,1)=2*НОД(1,1)=2

НОД: 2

Задание 4.

def gcd_binary(a, b): step = 1 if a == 0: print(f"НОД: {b}") return b if b == 0: print(f"НОД: {a}") return a shift = 0 while (a | b) & 1 == 0: a, b = a >> 1, b >> 1 shift += 1 while a & 1 == 0: a >>= 1 while b: while b & 1 == 0: b >>= 1 if a > b: a, b = b, a b -= a print(f"Шаг {step}: a = {a}, b = {b}") step += 1 gcd = a << shift print(f"НОД: {gcd}") return gcd a = int(input("Введите первое число: ")) b = int(input("Введите второе число: ")) gcd_binary(a, b)

Введите первое число: 1111492

Введите второе число: 564422

Шаг 1: a = 277873, b = 4338

Шаг 2: a = 2169, b = 275704

Шаг 3: a = 2169, b = 32294

Шаг 4: a = 2169, b = 13978

Шаг 5: a = 2169, b = 4820

Шаг 6: a = 1205, b = 964

Шаг 7: a = 241, b = 964

Шаг 8: a = 241, b = 0

НОД: 482

Вариант 16

Задание 1

a = 20

b = 12

20 = 12 * 1 + 8

12 = 8 * 1 + 4

8 = 4 * 2 + 0

НОД = 4

Задание 2

a = 1542844

b = 775042

Код программы:

def evklide(a, b): while b != 0: r = a%b q = a // b print (f"{a} = {q}*{b} + {r}") a = b b = r print(f"НОД равен {a}") num1 = int(input("Введите число 1: ")) num2 = int(input("Введите число 2: ")) evklide(num1, num2)

Вывод программы:

Введите число 1: 1542844

Введите число 2: 775042

1542844 = 1*775042 + 767802

775042 = 1*767802 + 7240

767802 = 106*7240 + 362

7240 = 20*362 + 0

НОД равен 362

Задание 3

НОД(20,12) = 2*НОД(10,6) = 4*НОД(5,3) =

= 4*НОД(5-3,3) = 4*НОД(2,3) = 4*НОД(3-2,2) = 4*НОД(2,1) =

= 4*НОД(2-1,1)=4*НОД(1,1)

НОД = 4

Задание 4

Код программы:

def binary_gcd_algorithm(a, b): if a == 0: return b, [(a, b, 0)] if b == 0: return a, [(a, b, 0)] g = 1 steps = [] while a % 2 == 0 and b % 2 == 0: a //= 2 b //= 2 g *= 2 steps.append((a, b, g)) u, v = a, b while u != 0: while u % 2 == 0: u //= 2 steps.append((u, v, g)) while v % 2 == 0: v //= 2 steps.append((u, v, g)) if u >= v: u -= v else: v -= u steps.append((u, v, g)) return g * v, steps num1 = int(input("Введите первое число: ")) num2 = int(input("Введите второе число: ")) result, intermediate_steps = binary_gcd_algorithm(num1, num2) print(f"НОД равен {result}") print("\nПромежуточные шаги:") for step in intermediate_steps: print(f"{step[0]} = {step[1]} + {step[2]} * 2^{step[2]}")

Вывод программы:

Введите первое число: 1542844

Введите второе число: 775042

Промежуточные шаги:

771422 = 387521 + 2 * 2^2

385711 = 387521 + 2 * 2^2

385711 = 1810 + 2 * 2^2

385711 = 905 + 2 * 2^2

384806 = 905 + 2 * 2^2

192403 = 905 + 2 * 2^2

191498 = 905 + 2 * 2^2

95749 = 905 + 2 * 2^2

94844 = 905 + 2 * 2^2

47422 = 905 + 2 * 2^2

23711 = 905 + 2 * 2^2

22806 = 905 + 2 * 2^2

11403 = 905 + 2 * 2^2

10498 = 905 + 2 * 2^2

5249 = 905 + 2 * 2^2

4344 = 905 + 2 * 2^2

2172 = 905 + 2 * 2^2

1086 = 905 + 2 * 2^2

543 = 905 + 2 * 2^2

543 = 362 + 2 * 2^2

543 = 181 + 2 * 2^2

362 = 181 + 2 * 2^2

181 = 181 + 2 * 2^2

0 = 181 + 2 * 2^2

НОД равен 362

Соседние файлы в предмете Математические основы защиты информации