“สวัสดี อามีโก้!”

"ถึงเวลาสำหรับหัวข้อที่น่าสนใจอื่น: การเข้ารหัส"

"บางทีคุณอาจเคยได้ยินที่ไหนสักแห่งว่าอักขระแต่ละตัวมีรหัส (ตัวเลข) นั่นเป็นสาเหตุที่ประเภทอักขระสามารถแสดงได้ทั้งสัญลักษณ์และตัวเลข"

"ตัวอย่างเช่น รหัสสำหรับตัวอักษร 'A' ในตัวอักษรภาษาอังกฤษคือ 65 'B' คือ 66, 'C' คือ 67 และอื่น ๆ มีรหัสเฉพาะสำหรับตัวอักษรพิมพ์ใหญ่ ตัวอักษรพิมพ์เล็ก อักษรซิริลลิก ภาษาจีน อักขระ (ใช่ รหัสมากมาย) ตัวเลข และสัญลักษณ์ต่างๆ กล่าวโดยย่อ คือ มีรหัสสำหรับทุกสิ่งที่คุณเรียกว่าอักขระ"

"ตัวอักษรและอักขระทุกตัวสอดคล้องกับตัวเลขหรือไม่"

"แม่นยำ."

"อักขระสามารถแปลงเป็นตัวเลข และแปลงตัวเลขเป็นอักขระได้ โดยทั่วไป Java จะไม่เห็นความแตกต่างระหว่างอักขระเหล่านี้:"

char c = 'A'; //The code (number) for 'A' is 65
c++; //Now c contains the number 66, which is the code for 'B'

"น่าสนใจ."

"ดังนั้น การเข้ารหัสคือชุดของสัญลักษณ์และชุดของรหัสที่สอดคล้องกัน แต่ไม่ได้มีเพียงการเข้ารหัสเดียวที่ถูกประดิษฐ์ขึ้น - มีค่อนข้างน้อย จนกระทั่งต่อมาได้มีการคิดค้นการเข้ารหัสสากล Unicode"

"แต่ไม่ว่าจะคิดค้นมาตรฐานสากลมากมายเพียงใด ก็ไม่มีใครรีบละทิ้งมาตรฐานเก่า แล้วทุกอย่างก็เกิดขึ้นเหมือนในการ์ตูนเรื่องนี้:"

การเข้ารหัสอักขระ - 1

"ลองจินตนาการว่า Vincent และ Nick ตัดสินใจทำการเข้ารหัสด้วยตัวเอง"

"นี่คือการเข้ารหัสของ Vincent:"
การเข้ารหัสอักขระ - 2

"และนี่คือการเข้ารหัสของ Nick:"
การเข้ารหัสอักขระ - 3

"พวกเขาใช้อักขระเดียวกัน แต่รหัสสำหรับอักขระต่างกัน"

"เมื่อสตริง 'ABC-123' ถูกเขียนลงในไฟล์โดยใช้การเข้ารหัสของ Vincent เราจะได้ชุดของไบต์ต่อไปนี้:"
การเข้ารหัสอักขระ - 4

"และตอนนี้โปรแกรมอื่นที่ใช้การเข้ารหัสของ Nick ต้องการอ่านไฟล์:"

"นี่คือสิ่งที่จะอ่าน: «345-IJK»"

"และสิ่งที่เลวร้ายที่สุดคือการเข้ารหัสโดยทั่วไปจะไม่ถูกจัดเก็บไว้ในที่ใดในไฟล์ ดังนั้นนักพัฒนาจึงต้องคาดเดา"

"แล้วพวกเขาเดาได้อย่างไร"

"นั่นเป็นหัวข้อที่แตกต่างกัน แต่ฉันอยากจะอธิบายวิธีการทำงานกับการเข้ารหัส ดังที่คุณทราบแล้ว ขนาดของอักขระใน Java คือสองไบต์ และ Java Strings ใช้รูปแบบ Unicode"

"แต่ Java ให้คุณแปลงสตริงเป็นชุดของไบต์ในการเข้ารหัสใดๆ ที่มันรู้ คลาสสตริงมีวิธีพิเศษสำหรับสิ่งนี้ Java ยังมีคลาส Charset พิเศษที่อธิบายการเข้ารหัสเฉพาะ"

1) ฉันจะรับรายการการเข้ารหัสทั้งหมดที่ Java รองรับได้อย่างไร

"มีเมธอดสแตติกพิเศษที่เรียกว่า availableCharsets สำหรับสิ่งนั้น "เมธอดนี้ส่งคืนชุดของคู่ (ชื่อการเข้ารหัส วัตถุที่อธิบายการเข้ารหัส):"

SortedMap<String,Charset> charsets = Charset.availableCharsets();

"การเข้ารหัสแต่ละตัวมีชื่อที่ไม่ซ้ำกัน นี่คือบางส่วน: UTF-8, UTF-16, Windows-1251, KOI8-R, …"

2) ฉันจะรับการเข้ารหัสที่ใช้งานอยู่ในปัจจุบัน (Unicode) ได้อย่างไร

"มีวิธีพิเศษที่เรียกว่าdefaultCharsetสำหรับสิ่งนั้น

Charset currentCharset = Charset.defaultCharset();

3) ฉันจะแปลงสตริงเป็นการเข้ารหัสเฉพาะได้อย่างไร

"ใน Java คุณสามารถแปลงสตริงเป็นอาร์เรย์ไบต์ในการเข้ารหัสใดๆ ที่ Java รู้จัก:"

วิธี ตัวอย่าง
byte[] getBytes()
String s = "Good news, everyone!";
byte[] buffer = s.getBytes()
byte[] getBytes(Charset charset)
String s = "Good news, everyone!";
Charset koi8 = Charset.forName("KOI8-R");
byte[] buffer = s.getBytes(koi8);
byte[] getBytes(String charsetName)
String s = "Good news, everyone!";
byte[] buffer = s.getBytes("Windows-1251")

4) ฉันจะแปลงอาร์เรย์ไบต์ที่ฉันอ่านจากไฟล์เป็นสตริงได้อย่างไร หากฉันรู้ว่ามีการเข้ารหัสอะไรอยู่ในไฟล์

"นี่เป็นเรื่องง่ายยิ่งขึ้นคลาส String มีตัวสร้างพิเศษ:"

วิธี ตัวอย่าง
String(byte bytes[])
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer);
String(byte bytes[], Charset charset)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

Charset koi8 = Charset.forName("KOI8-R");
String s = new String(buffer, koi8);
String(byte bytes[], String charsetName)
byte[] buffer = new byte[1000];
inputStream.read(buffer);

String s = new String(buffer, "Windows-1251");

5) ฉันจะแปลงอาร์เรย์ไบต์จากการเข้ารหัสหนึ่งไปยังอีกการเข้ารหัสหนึ่งได้อย่างไร

"มีหลายวิธี วิธีที่ง่ายที่สุดวิธีหนึ่งคือ"

Charset koi8 = Charset.forName("KOI8-R");
Charset windows1251 = Charset.forName("Windows-1251");

byte[] buffer = new byte[1000];
inputStream.read(buffer);
String s = new String(buffer, koi8);
buffer = s.getBytes(windows1251);
outputStream.write(buffer);

"นั่นคือสิ่งที่ฉันคิด ขอบคุณสำหรับบทเรียนที่น่าสนใจ ริชิ"