체크섬(checksum)은 네트워크를 통해 데이터를 전송할 때 발생할 수 있는 오류를 검출하기 위해 널리 사용되는 대표적인 오류 검출 기법입니다. 송신 측에서 데이터를 기반으로 특정 값을 계산해 함께 전송하면, 수신 측에서 동일한 방식으로 값을 다시 계산하여 두 값을 비교함으로써 데이터가 전송 중에 변형되지 않았는지 확인할 수 있습니다.
다음은 Java를 사용하여 체크섬을 구현하는 코드입니다.
예제 코드
import java.util.*;
public class Demo{
public static void main(String args[]){
Scanner my_scan = new Scanner(System.in);
System.out.println("Enter the input string ");
String my_in = my_scan.next();
int my_checksum = generate_checksum(my_in);
System.out.println("The checksum that has been generated is " + Integer.toHexString(my_checksum));
System.out.println("Enter the data that needs to be sent to the receiver ");
my_in = my_scan.next();
System.out.println("Enter the checksum that needs to be sent to the receiver ");
my_checksum = Integer.parseInt((my_scan.next()), 16);
receive(my_in, my_checksum);
my_scan.close();
}
static int generate_checksum(String s){
String my_hex_val = new String();
int x, i, my_checksum = 0;
for (i = 0; i < s.length() - 2; i = i + 2){
x = (int) (s.charAt(i));
my_hex_val = Integer.toHexString(x);
x = (int) (s.charAt(i + 1));
my_hex_val = my_hex_val + Integer.toHexString(x);
System.out.println(s.charAt(i) + "" + s.charAt(i + 1) + " : " + my_hex_val);
x = Integer.parseInt(my_hex_val, 16);
my_checksum += x;
}
if (s.length() % 2 == 0){
x = (int) (s.charAt(i));
my_hex_val = Integer.toHexString(x);
x = (int) (s.charAt(i + 1));
my_hex_val = my_hex_val + Integer.toHexString(x);
System.out.println(s.charAt(i) + "" + s.charAt(i + 1) + " : "+ my_hex_val);
x = Integer.parseInt(my_hex_val, 16);
} else {
x = (int) (s.charAt(i));
my_hex_val = "00" + Integer.toHexString(x);
x = Integer.parseInt(my_hex_val, 16);
System.out.println(s.charAt(i) + " : " + my_hex_val);
}
my_checksum += x;
my_hex_val = Integer.toHexString(my_checksum);
if (my_hex_val.length() > 4){
int carry = Integer.parseInt(("" + my_hex_val.charAt(0)), 16);
my_hex_val = my_hex_val.substring(1, 5);
my_checksum = Integer.parseInt(my_hex_val, 16);
my_checksum += carry;
}
my_checksum = generate_complement(my_checksum);
return my_checksum;
}
static void receive(String s, int my_checksum){
int gen_checksum = generate_checksum(s);
gen_checksum = generate_complement(gen_checksum);
int syndrome = gen_checksum + my_checksum;
syndrome = generate_complement(syndrome);
System.out.println("The value of syndrome is " + Integer.toHexString(syndrome));
if (syndrome == 0){
System.out.println("Data has been received without any errors");
} else {
System.out.println("An error was encountered in the received data");
}
}
static int generate_complement(int my_checksum){
my_checksum = Integer.parseInt("FFFF", 16) - my_checksum;
return my_checksum;
}
}입력
sample sample b2c8
출력
Enter the input string sa : 7361 mp : 6d70 le : 6c65 The checksum that has been generated is b2c8 Enter the data that needs to be sent to the receiver Enter the checksum that needs to be sent to the receiver sa : 7361 mp : 6d70 le : 6c65 The value of syndrome is 0 Data has been received without any errors
코드 설명
main 메서드
Demo라는 이름의 클래스에는 프로그램의 진입점인 main 메서드가 포함되어 있습니다. 이 메서드에서는 Scanner 인스턴스를 생성하여 사용자로부터 입력 문자열을 받아오고, 이를 바탕으로 체크섬을 생성합니다. 이후 수신 측에 보낼 데이터와 체크섬 값을 추가로 입력받아 receive 메서드를 호출한 뒤 Scanner를 닫습니다.
generate_checksum 메서드
'generate_checksum' 메서드는 새로운 문자열 인스턴스를 생성하고 체크섬 값을 0으로 초기화합니다. 매개변수로 전달된 문자열은 두 글자씩 묶어서 반복 처리되며, 각 문자는 먼저 정수 값으로 변환된 후 다시 16진수 값으로 변환됩니다. 그런 다음 현재 문자의 16진수 값과 다음 문자의 16진수 값이 연결되어 하나의 16진수 값으로 만들어지고, 이 값이 체크섬에 누적됩니다.
문자열의 길이가 짝수인 경우에는 마지막으로 남은 두 문자도 동일한 방식으로 처리됩니다. 반면 길이가 홀수인 경우에는 남은 한 문자의 16진수 값 앞에 '00'을 붙여 두 자리로 맞춘 뒤 처리합니다.
모든 문자의 처리가 끝나면 체크섬의 16진수 표현 길이가 4자리를 초과하는지 확인합니다. 초과하는 경우 자리올림(carry)이 발생한 것이므로, 최상위 자릿수를 자리올림 값으로 분리하여 나머지 값에 더해줍니다. 마지막으로 'generate_complement' 메서드를 호출하여 체크섬의 보수를 계산한 뒤 반환합니다.
receive 메서드
'receive' 메서드는 수신된 데이터에 대해 'generate_checksum' 메서드를 다시 호출하여 체크섬을 재계산합니다. 그런 다음 이 값과 수신 측에서 전달받은 원래의 체크섬 값을 더하고, 다시 보수를 취한 결과값인 신드롬(syndrome)을 구합니다. 신드롬 값이 0이면 데이터가 오류 없이 수신된 것으로 판단하고, 그렇지 않으면 수신된 데이터에 오류가 있다고 출력합니다.
generate_complement 메서드
'generate_complement' 메서드는 16진수 'FFFF'에서 체크섬 값을 빼는 방식으로 보수를 계산합니다. 이렇게 얻은 보수 값은 송신 측과 수신 측의 체크섬을 비교하여 데이터 무결성을 검증하는 데 활용됩니다.