상세 컨텐츠

본문 제목

Java 프로그래밍에서 인코딩 및 디코딩 이야기

언어/Java

by codeon 2024. 5. 31. 00:33

본문

반응형

Java 프로그래밍에서 인코딩 및 디코딩은 데이터를 한 형식에서 다른 형식으로 변환하는 프로세스를 나타냅니다. 이러한 프로세스는 텍스트, 이진 데이터 또는 개체를 처리할 때 일반적으로 사용됩니다. 각 개념을 자세히 살펴보겠습니다.

 

인코딩

텍스트 인코딩

여기에는 텍스트 문자를 특정 바이트 표현으로 변환하는 작업이 포함됩니다. 예를 들어 UTF-8 또는 UTF-16과 같은 특정 문자 인코딩을 사용하여 문자열을 바이트 시퀀스로 변환합니다. 이 프로세스는 텍스트 데이터를 바이너리 형식으로 저장하거나 전송하는 데 필수적입니다.

import java.nio.charset.Charset;

public class UnicodeTest {

	public static void main(String[] args) {
		String text = "한";

		System.out.println("## this Java virtual machine : " + Charset.defaultCharset());
		System.out.println("## text this machine byte length :" + text.getBytes().length);
		System.out.println("## text UTF-8 byte length :" + text.getBytes(Charset.forName("UTF-8")).length);
		System.out.println("## text Unicode byte length :" + text.getBytes(Charset.forName("Unicode")).length);
		System.out.println("## text UTF16 byte length :" + text.getBytes(Charset.forName("UTF-16")).length);

		String text2 = "한국";

		System.out.println('\u0009');
		System.out.println("## text this machine byte length :" + text2.getBytes().length);
		
		String utf8Text = new String(text2.getBytes(), Charset.forName("UTF-8"));
		System.out.println("## utf8 text : " + utf8Text);
		System.out.println("## text UTF-8 -> UTF-8 length :" + utf8Text.getBytes().length);
		
		String unicodeText = new String(text2.getBytes(), Charset.forName("Unicode"));
		System.out.println("## unicode text : " + unicodeText);
		System.out.println("## unicode text -> UTF-8 text :" + new String(unicodeText.getBytes(Charset.forName("Unicode")), Charset.forName("UTF-8")));
		System.out.println("## text UTF-8 -> Unicode length :" + unicodeText.getBytes(Charset.forName("Unicode")).length);
		
		System.out.println('\u0009');
		String unicodeText2 = new String(text2.getBytes(Charset.forName("Unicode")));
		System.out.println("## unicode text2 : " + unicodeText2);
		System.out.println("## unicode text2 -> UTF-8 text :" + new String(unicodeText2.getBytes(), Charset.forName("UTF-8")));
		System.out.println("## unicode text2 -> UTF-8 text :" + new String(unicodeText2.getBytes(Charset.forName("Unicode")), Charset.forName("UTF-8")));
		System.out.println("## unicode text2 UTF-8 -> Unicode length :" + unicodeText2.getBytes(Charset.forName("Unicode")).length);
		
		System.out.println('\u0009');
		String utf16Text = new String(text2.getBytes(), Charset.forName("UTF-16"));
		System.out.println("## utf16 text : " + utf16Text);
		System.out.println("## text UTF-8 -> UTF-16 length :" + utf16Text.getBytes(Charset.forName("UTF-16")).length);
		System.out.println("## UTF-16 text -> UTF-8 text :" + new String(utf16Text.getBytes(Charset.forName("UTF-16")), Charset.forName("UTF-8")));
	}
}

 

아래의 결과를 잘 확인해 주시기 바랍니다. 인코딩 디코딩시 반드시 현재 VM의 설정 인코딩 타입을 반드시 고려한 코드가 나와 줘야 합니다. 기본적으로 getByte()를 인자 없이 쓰게 되면 시스템 설정 인코딩 타입이 사용되게 됩니다. 

인코딩 디코딩 실행 결과

객체 직렬화

Java 객체는 직렬화될 수 있습니다. 즉, 파일에 저장하거나 네트워크를 통해 전송할 수 있는 바이트 스트림으로 변환됩니다. 이 프로세스는 객체 상태를 유지하거나 다른 Java 애플리케이션 간에 객체를 전송하는 데 중요합니다.

// Assume 'objectToSerialize' is an instance of a Serializable class
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.ser"))) {
    oos.writeObject(objectToSerialize);
} catch (IOException e) {
    e.printStackTrace();
}

// ======================================================================================

try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"))) {
    Object deserializedObject = ois.readObject();
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

 

 

압축

인코딩에는 효율적인 저장 또는 전송을 위해 데이터 크기를 줄이는 압축이 포함될 수도 있습니다. Java는 Deflate와 같은 알고리즘을 사용하여 데이터를 압축하기 위한 java.util.zip과 같은 라이브러리를 제공합니다.

byte[] dataToCompress = ...; // Data to compress
ByteArrayOutputStream compressedStream = new ByteArrayOutputStream();
try (DeflaterOutputStream dos = new DeflaterOutputStream(compressedStream)) {
    dos.write(dataToCompress);
} catch (IOException e) {
    e.printStackTrace();
}
byte[] compressedData = compressedStream.toByteArray();

// ======================================================================================
byte[] compressedData = ...; // Compressed data
ByteArrayOutputStream decompressedStream = new ByteArrayOutputStream();
try (InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(compressedData))) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = iis.read(buffer)) != -1) {
        decompressedStream.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}
byte[] decompressedData = decompressedStream.toByteArray();

암호화

인코딩에는 암호 해독 키 없이는 읽을 수 없도록 데이터가 변환되는 암호화가 포함될 수 있습니다. Java는 데이터를 안전하게 암호화하고 해독하기 위해 javax.crypto와 같은 암호화 라이브러리를 제공합니다.

String originalText = "Sensitive data to encrypt";
SecretKey secretKey = generateSecretKey(); // Method to generate a secret key
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedData = cipher.doFinal(originalText.getBytes(StandardCharsets.UTF_8));

// ======================================================================================

byte[] encryptedData = ...; // Encrypted data
SecretKey secretKey = retrieveSecretKey(); // Method to retrieve the secret key
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
String decryptedText = new String(decryptedData, StandardCharsets.UTF_8);

 

반응형

관련글 더보기