📜  Python中的循环冗余检查

📅  最后修改于: 2022-05-13 01:54:22.090000             🧑  作者: Mango

Python中的循环冗余检查

先决条件:了解循环冗余、套接字编程

什么是 CRC?
CRC 或循环冗余校验是一种检测通信通道中意外更改/错误的方法。
CRC 使用在发送方和接收方都可用的生成多项式。一个示例生成多项式的形式为 x^3 + 1。该生成多项式表示密钥 1001。另一个示例是 x^2 + x。表示键 110。

例子:
让数据发送为“EVN”
我们将字符串转换为二进制字符串数据。

Python
input_string = "EVN"
 
# CONVERT string data to binary string data
data = (''.join(format(ord(x), 'b') for x in input_string))
print (data)


Python3
# Import socket module
import socket           
 
def xor(a, b):
 
    # initialize result
    result = []
 
    # Traverse all bits, if bits are
    # same, then XOR is 0, else 1
    for i in range(1, len(b)):
        if a[i] == b[i]:
            result.append('0')
        else:
            result.append('1')
 
    return ''.join(result)
 
 
# Performs Modulo-2 division
def mod2div(divident, divisor):
 
    # Number of bits to be XORed at a time.
    pick = len(divisor)
 
    # Slicing the divident to appropriate
    # length for particular step
    tmp = divident[0 : pick]
 
    while pick < len(divident):
 
        if tmp[0] == '1':
 
            # replace the divident by the result
            # of XOR and pull 1 bit down
            tmp = xor(divisor, tmp) + divident[pick]
 
        else: # If leftmost bit is '0'
 
            # If the leftmost bit of the dividend (or the
            # part used in each step) is 0, the step cannot
            # use the regular divisor; we need to use an
            # all-0s divisor.
            tmp = xor('0'*pick, tmp) + divident[pick]
 
        # increment pick to move further
        pick += 1
 
    # For the last n bits, we have to carry it out
    # normally as increased value of pick will cause
    # Index Out of Bounds.
    if tmp[0] == '1':
        tmp = xor(divisor, tmp)
    else:
        tmp = xor('0'*pick, tmp)
 
    checkword = tmp
    return checkword
 
# Function used at the sender side to encode
# data by appending remainder of modular division
# at the end of data.
def encodeData(data, key):
 
    l_key = len(key)
 
    # Appends n-1 zeroes at end of data
    appended_data = data + '0'*(l_key-1)
    remainder = mod2div(appended_data, key)
 
    # Append remainder in the original data
    codeword = data + remainder
    return codeword   
     
# Create a socket object
s = socket.socket()       
 
# Define the port on which you want to connect
port = 12345           
 
# connect to the server on local computer
s.connect(('127.0.0.1', port))
 
# Send data to server 'Hello world'
 
## s.sendall('Hello World')
 
input_string = input("Enter data you want to send->")
#s.sendall(input_string)
data =(''.join(format(ord(x), 'b') for x in input_string))
print("Entered data in binary format :",data)
key = "1001"
 
ans = encodeData(data,key)
print("Encoded data to be sent to server in binary format :",ans)
s.sendto(ans.encode(),('127.0.0.1', 12345))
 
 
# receive data from the server
print("Received feedback from server :",s.recv(1024).decode())
 
# close the connection
s.close()


Python3
# First of all import the socket library
import socket
 
 
def xor(a, b):
 
    # initialize result
    result = []
 
    # Traverse all bits, if bits are
    # same, then XOR is 0, else 1
    for i in range(1, len(b)):
        if a[i] == b[i]:
            result.append('0')
        else:
            result.append('1')
 
    return ''.join(result)
 
 
# Performs Modulo-2 division
def mod2div(divident, divisor):
 
    # Number of bits to be XORed at a time.
    pick = len(divisor)
 
    # Slicing the divident to appropriate
    # length for particular step
    tmp = divident[0: pick]
 
    while pick < len(divident):
 
        if tmp[0] == '1':
 
            # replace the divident by the result
            # of XOR and pull 1 bit down
            tmp = xor(divisor, tmp) + divident[pick]
 
        else:  # If leftmost bit is '0'
            # If the leftmost bit of the dividend (or the
            # part used in each step) is 0, the step cannot
            # use the regular divisor; we need to use an
            # all-0s divisor.
            tmp = xor('0'*pick, tmp) + divident[pick]
 
        # increment pick to move further
        pick += 1
 
    # For the last n bits, we have to carry it out
    # normally as increased value of pick will cause
    # Index Out of Bounds.
    if tmp[0] == '1':
        tmp = xor(divisor, tmp)
    else:
        tmp = xor('0'*pick, tmp)
 
    checkword = tmp
    return checkword
 
# Function used at the receiver side to decode
# data received by sender
 
 
def decodeData(data, key):
 
    l_key = len(key)
 
    # Appends n-1 zeroes at end of data
    appended_data = data.decode() + '0'*(l_key-1)
    remainder = mod2div(appended_data, key)
 
    return remainder
 
 
# Creating Socket
s = socket.socket()
print("Socket successfully created")
 
# reserve a port on your computer in our
# case it is 12345 but it can be anything
port = 12345
 
s.bind(('', port))
print("socket binded to %s" % (port))
# put the socket into listening mode
s.listen(5)
print("socket is listening")
 
 
while True:
    # Establish connection with client.
    c, addr = s.accept()
    print('Got connection from', addr)
 
    # Get data from client
    data = c.recv(1024)
 
    print("Received encoded data in binary format :", data.decode())
 
    if not data:
        break
 
    key = "1001"
 
    ans = decodeData(data, key)
    print("Remainder after decoding is->"+ans)
 
    # If remainder is all zeros then no error occured
    temp = "0" * (len(key) - 1)
    if ans == temp:
        c.sendto(("THANK you Data ->"+data.decode() +
                  " Received No error FOUND").encode(), ('127.0.0.1', 12345))
    else:
        c.sendto(("Error in data").encode(), ('127.0.0.1', 12345))
 
    c.close()


输出
100010110101101001110

CRC 密钥:1001
代码:CRC 密钥长度 -1 -> 000 附加在数据末尾。

New data: 100010110101101001110000
Key:1001

现在我们在发送方和接收方的套接字编程Python中应用 CRC。

发送方

1. 任务是将字符串数据发送到服务器/接收端。
2. 发送者发送一个字符串让我们说“EVN”。
3. 首先,将该字符串转换为二进制字符串“100010110101101001110” 密钥对于发送方和接收方来说都是已知的,这里使用的密钥是 1001。
4. 该数据使用客户端/发送方的密钥使用 CRC 码进行编码。
5. 这个编码数据被发送到接收器。
6. 接收方稍后对编码的数据字符串进行解码,以验证是否有任何错误。

Python3

# Import socket module
import socket           
 
def xor(a, b):
 
    # initialize result
    result = []
 
    # Traverse all bits, if bits are
    # same, then XOR is 0, else 1
    for i in range(1, len(b)):
        if a[i] == b[i]:
            result.append('0')
        else:
            result.append('1')
 
    return ''.join(result)
 
 
# Performs Modulo-2 division
def mod2div(divident, divisor):
 
    # Number of bits to be XORed at a time.
    pick = len(divisor)
 
    # Slicing the divident to appropriate
    # length for particular step
    tmp = divident[0 : pick]
 
    while pick < len(divident):
 
        if tmp[0] == '1':
 
            # replace the divident by the result
            # of XOR and pull 1 bit down
            tmp = xor(divisor, tmp) + divident[pick]
 
        else: # If leftmost bit is '0'
 
            # If the leftmost bit of the dividend (or the
            # part used in each step) is 0, the step cannot
            # use the regular divisor; we need to use an
            # all-0s divisor.
            tmp = xor('0'*pick, tmp) + divident[pick]
 
        # increment pick to move further
        pick += 1
 
    # For the last n bits, we have to carry it out
    # normally as increased value of pick will cause
    # Index Out of Bounds.
    if tmp[0] == '1':
        tmp = xor(divisor, tmp)
    else:
        tmp = xor('0'*pick, tmp)
 
    checkword = tmp
    return checkword
 
# Function used at the sender side to encode
# data by appending remainder of modular division
# at the end of data.
def encodeData(data, key):
 
    l_key = len(key)
 
    # Appends n-1 zeroes at end of data
    appended_data = data + '0'*(l_key-1)
    remainder = mod2div(appended_data, key)
 
    # Append remainder in the original data
    codeword = data + remainder
    return codeword   
     
# Create a socket object
s = socket.socket()       
 
# Define the port on which you want to connect
port = 12345           
 
# connect to the server on local computer
s.connect(('127.0.0.1', port))
 
# Send data to server 'Hello world'
 
## s.sendall('Hello World')
 
input_string = input("Enter data you want to send->")
#s.sendall(input_string)
data =(''.join(format(ord(x), 'b') for x in input_string))
print("Entered data in binary format :",data)
key = "1001"
 
ans = encodeData(data,key)
print("Encoded data to be sent to server in binary format :",ans)
s.sendto(ans.encode(),('127.0.0.1', 12345))
 
 
# receive data from the server
print("Received feedback from server :",s.recv(1024).decode())
 
# close the connection
s.close()

接收端

1. 接收方接收来自发送方的编码数据字符串。
2. 接收器借助密钥对数据进行解码并找出余数。
3. 如果余数为零,则表示发送方发送给接收方的数据没有错误。
4. 如果余数不为零,则表示有错误,向发送者发送否定确认。然后发送方重新发送数据,直到接收方接收到正确的数据。

Python3

# First of all import the socket library
import socket
 
 
def xor(a, b):
 
    # initialize result
    result = []
 
    # Traverse all bits, if bits are
    # same, then XOR is 0, else 1
    for i in range(1, len(b)):
        if a[i] == b[i]:
            result.append('0')
        else:
            result.append('1')
 
    return ''.join(result)
 
 
# Performs Modulo-2 division
def mod2div(divident, divisor):
 
    # Number of bits to be XORed at a time.
    pick = len(divisor)
 
    # Slicing the divident to appropriate
    # length for particular step
    tmp = divident[0: pick]
 
    while pick < len(divident):
 
        if tmp[0] == '1':
 
            # replace the divident by the result
            # of XOR and pull 1 bit down
            tmp = xor(divisor, tmp) + divident[pick]
 
        else:  # If leftmost bit is '0'
            # If the leftmost bit of the dividend (or the
            # part used in each step) is 0, the step cannot
            # use the regular divisor; we need to use an
            # all-0s divisor.
            tmp = xor('0'*pick, tmp) + divident[pick]
 
        # increment pick to move further
        pick += 1
 
    # For the last n bits, we have to carry it out
    # normally as increased value of pick will cause
    # Index Out of Bounds.
    if tmp[0] == '1':
        tmp = xor(divisor, tmp)
    else:
        tmp = xor('0'*pick, tmp)
 
    checkword = tmp
    return checkword
 
# Function used at the receiver side to decode
# data received by sender
 
 
def decodeData(data, key):
 
    l_key = len(key)
 
    # Appends n-1 zeroes at end of data
    appended_data = data.decode() + '0'*(l_key-1)
    remainder = mod2div(appended_data, key)
 
    return remainder
 
 
# Creating Socket
s = socket.socket()
print("Socket successfully created")
 
# reserve a port on your computer in our
# case it is 12345 but it can be anything
port = 12345
 
s.bind(('', port))
print("socket binded to %s" % (port))
# put the socket into listening mode
s.listen(5)
print("socket is listening")
 
 
while True:
    # Establish connection with client.
    c, addr = s.accept()
    print('Got connection from', addr)
 
    # Get data from client
    data = c.recv(1024)
 
    print("Received encoded data in binary format :", data.decode())
 
    if not data:
        break
 
    key = "1001"
 
    ans = decodeData(data, key)
    print("Remainder after decoding is->"+ans)
 
    # If remainder is all zeros then no error occured
    temp = "0" * (len(key) - 1)
    if ans == temp:
        c.sendto(("THANK you Data ->"+data.decode() +
                  " Received No error FOUND").encode(), ('127.0.0.1', 12345))
    else:
        c.sendto(("Error in data").encode(), ('127.0.0.1', 12345))
 
    c.close()

输出

笔记:
如何运行程序:
1.你应该有一个socket编程库。

2.首先运行服务器程序,然后运行客户端程序。

3.复制粘贴代码时可能会出现缩进错误,所以复制时要小心。

4. 您将在拆分终端中看到以下输出。