Руководство по HamsterCMS от TomoTomoTan
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Предисловие и глава 1. - Как включить
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 2 - О шаблонах и содержимом
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 3 - Доступ к сайту через FTP, редактирование шаблона
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 4 - Устройство шаблона. Немного о включениях.
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 5 - Создание собственного шаблона. Загрузка файлов на сайт с помощью WebFTP

Cyclic redundancy check (CRC)

Moderator: push0ret

User avatar
push0ret
Набирающий обороты
Posts: 34
Joined: Sun Dec 29, 2024 2:48 pm
Has thanked: 22 times
Been thanked: 28 times

Cyclic redundancy check (CRC)

Post by push0ret »

Циклическая проверка избыточности (CRC) - алгоритм нахождения контрольной суммы. Для чего же нужна контрольная сумма?

Чаще всего:

1. Используется для проверки целостности данных, ведь при изменении хотя бы одного бита, контрольная сумма будет отличаться от исходной.
2. Для шифрования. Контрольная сумма в этом случае является ключом шифрования.

Результатом алгоритма могут быть числа разной разрядности. Есть разные варианты алгоритма CRC: CRC-1, CRC-8, CRC-16, CRC-32 и т.д.. Важно понимать, что зная алгоритм, мы можем использовать числа любой разрядности, в зависимости от задачи.

Алгоритм вычисления CRC-16, который я использовал для примера:

1. Обнулить CRC (размер CRC равен 4 байтам).
2. Если длина оставшейся части исходной информации равна нулю, то перейти к п. 8.
3. Сдвинуть CRC влево на 8 разрядов.
4. Обнулить старший байт CRC. (Из-за особенностей 16-разрядной архитектуры процессора)
5. Считать в младший байт CRC очередной байт исходной информации.
6. Разделить CRC на число 11021d.
7. Поместить остаток в CRC.
8. Перейти к п. 2.
9. Инвертировать CRC. В младших двух байтах CRC - контрольная сумма.

Пример:

Code: Select all

.286
.model	tiny
code	segment
org	100h

;Calculation of the checksum.
;CRC-16. 

start:

;User enter numbers.

mov ah, 0Ah
mov dx, offset array
int 21h

mov si, offset array+2
mov cl, byte ptr [si-1]

;Calculate CRC

xor dx, dx
xor ax, ax

mov bx, 11021d

calculate:

push cx
mov cx, 8d

shift:

rcl ax, 1d
rcl dx, 1d
loop shift

xor dh, dh

mov al, byte ptr [si]
div bx

mov ax, dx

inc si
pop cx

loop calculate

not ax

;Translate hex number in ASCII code for display.

mov cl, 4d
mov di, offset msg

hex_ascii:

rol ax, 4d
mov bx, ax
and ax, 0Fh

cmp al, 9d
ja letter

add al, 30h
mov byte ptr [di+2], al
mov ax, bx
inc di

loop hex_ascii

jmp exit

letter:

add al, 37h
mov byte ptr [di+2], al
inc di
mov ax, bx

loop hex_ascii

exit:

;Display CRC.

mov ah, 9d
mov dx, offset msg
int 21h

mov ax, 4C00h
int 21h

array	db	255d, 257d dup(0)
msg	db	0Ah, 0Dh, 4d dup(0), 24h

code	ends
end	start
Программа ожидает ввода с клавиатуры от пользователя максимальной длинной 255 символов (чисел) и вычисляет CRC массива, введённого с клавиатуры, после чего контрольная сумма выводится на экран.

Результат работы программы:
CRC.PNG
Шифрование пакета данных с помощью контрольной суммы:

Code: Select all

.286
.model  tiny
code    segment
org     100h

;Transmission of frames with encryption.

start:

;COM1 INIT

mov dx, 3FBh
in al, dx
or al, 10000000b
out dx, al

;9600 baud

mov dx, 3F8h
mov al, 12d
out dx, al

mov dx, 3FBh
in al, dx
and al, 01111111b
out dx, al

;8 bit, 1 stop bit, no parity

mov al, 00010011b
out dx, al

;Wait byte for receive or press key for transmit

wait_action:

in al, 60h
cmp al, 90h
jz transmit

mov dx, 3FDh
in al, dx

test al, 1d
jz wait_action

mov dx, 3F8h
in al, dx

cmp al, '$'
jz receive_msg

jmp wait_action

;Receive message block

receive_msg:

mov di, offset rx_crypto

;Wait byte

wait_byte:

mov dx, 3FDh
in al, dx

test al, 1d
jz wait_byte

mov dx, 3F8h
in al, dx

cmp al, '$'
jz stop_rx

cmp al, '@'
jz exit

mov byte ptr [di], al
inc di

jmp wait_byte

stop_rx:

mov byte ptr [di], 24h

;Receive checksum

wait_chksum:

mov dx, 3FDh
in al, dx

test al, 1d
jz wait_chksum

mov dx, 3F8h
in al, dx

mov crc, al

;Transcription message

transcript:

mov si, offset rx_crypto
mov di, offset rx_buffer

transcription:

mov al, byte ptr [si]

cmp al, '$'
jz display

xor al, crc
mov byte ptr [di], al
inc si
inc di

jmp transcription

display:

mov byte ptr [di], '$'

mov ah, 9h
mov dx, offset msg_display
int 21h

mov ah, 9d
mov dx, offset rx_crypto
int 21h

mov ah, 9d
mov dx, offset msg_display2
int 21h

mov ah, 9d
mov dx, offset rx_buffer
int 21h

mov ah, 9d
mov dx, offset msg_wait
int 21h

xor ax, ax

jmp wait_action

;Transmit message block

transmit:

mov ah, 9d
mov dx, offset msg_ent
int 21h

;User enter message

mov ah, 0Ah
mov dx, offset tx_buffer
int 21h

;Format array for transmit

mov si, dx
mov cl, byte ptr [si+1]
mov bl, cl
mov byte ptr [si+1], '$'
inc si
mov byte ptr [si+bx+1], '$'
add cx, 3d

push si
call crc_calc

mov dl, crc
mov byte ptr [si+bx+2], dl

transmit_byte:

mov dx, 3F8h
mov al, byte ptr [si]

cmp al, '$'
jz transmit_no_change

cmp al, crc
jz transmit_no_change

xor al, crc

transmit_no_change:

out dx, al

cmp al, '@'
jz exit

wait_tx:

mov dx, 3FDh
in al, dx
test al, 20h
jz wait_tx

inc si

loop transmit_byte

xor cx, cx

mov ah, 9d
mov dx, offset msg_wait
int 21h

xor ax, ax

jmp wait_action

exit:

mov ax, 4c00h
int 21h

;-----------------------------------------------------------
;CALCULATE CRC16 PROCEDURE.
;PARAMETERS(STACK):
;- OFFSET OF ARRAY OF BYTES COMPLETED WITH 0Ah DOS FUNCTION.
;OUT:
;- "CRC" VARIABLE CONTAINS A CHECKSUM.
;-----------------------------------------------------------

crc_calc	proc	uses bp ax dx cx si bx

xor dx, dx
xor ax, ax
xor cx, cx
mov bp, sp

mov bx, 11021d
mov si, word ptr ss:[bp+14]
mov cl, byte ptr [si-1]

calculate:

push cx
mov cx, 8d

shift:

rcl ax, 1d
rcl dx, 1d
loop shift

xor dh, dh

mov al, byte ptr [si]
div bx

mov ax, dx

inc si
pop cx

loop calculate

not ax

mov crc, al

ret 2

crc_calc	endp


tx_buffer	db	255d, 260d dup(0)
rx_buffer	db	256d dup(24h)
rx_crypto	db	256d dup(24h)
crc		db	?


msg_ent		db	0Ah, 0Dh, 'Enter message for transmit:', 0Ah, 0Dh, 24h
msg_wait	db	0Ah, 0Dh, 'Wait action...', 0Ah, 0Dh, 24h
msg_display	db	0Ah, 0Dh, 'Encrypted message:', 0Ah, 0Dh, 24h
msg_display2	db	0Ah, 0Dh, 'Decrypted message:', 0Ah, 0Dh, 24h

code    ends
end 	start
Программа инициализирует COM1 и при нажатии клавиши q предлагает пользователю ввести сообщение с клавиатуры, вычисляет контрольную сумму, совершает логическую операцию "исключающее ИЛИ" (xor) для каждого байта сообщения с контрольной суммой, после чего отправляет в COM1 зашифрованное сообщение и неизменённую контрольную сумму или ожидает приёма, на другой стороне загружена эта же программа. При приёме зашифрованного сообщения программа выводит на экран зашифрованное сообщение, затем производит логическую операцию "исключающее ИЛИ" (xor) для каждого байта зашифрованного сообщения и контрольной суммы, после чего выводит на экран расшифрованное сообщение.

Работа программы:



Спасибо за внимание!
С уважением, push0ret!
You do not have the required permissions to view the files attached to this post.

Code: Select all

push 0
ret
User avatar
september2489
Писака
Posts: 94
Joined: Fri Dec 27, 2024 4:29 pm
Has thanked: 42 times
Been thanked: 48 times

Re: Cyclic redundancy check (CRC)

Post by september2489 »

Спасибо, очень познавательно! Иногда при запуске всяких игр выскакивает CRC-ошибка, и некоторые игры можно запускать с параметром -no-crc, чтобы обойти эту ошибку, но далеко не все.

Вообще, проверка целостности - важная штука. Я в прошлом году изучал как устроены инфракрасные протоколы пультов дистанционного управления. Чаще всего, туда встраивают простую проверку, дублируя команду задом наперёд, но мне понравилось, как вышла из ситуации Sony. Инженеры просто оснастили свои бытовые устройства более мощным ИК-приёмником, который работает на большом расстоянии и под широкими углами, поэтому проверки CRC в их протоколах нет (в старых, во всяком случае).

Return to “Системное программирование”