Cách mã hóa UTF

Cách thực hiện mã hóa và giải mã Base64 trong Java, sử dụng API mới được giới thiệu trong Java 8 cũng như Apache Commons

Đọc thêm →

Hướng dẫn này là một hướng dẫn thực tế chỉ ra các cách khác nhau để mã hóa Chuỗi thành bộ ký tự UTF-8

Để tìm hiểu sâu hơn về kỹ thuật, hãy xem Hướng dẫn mã hóa ký tự của chúng tôi

2. Xác định vấn đề

Để giới thiệu cách mã hóa Java, chúng ta sẽ làm việc với Chuỗi tiếng Đức “Entwickeln Sie mit Vergnügen”

String germanString = "Entwickeln Sie mit Vergnügen";
byte[] germanBytes = germanString.getBytes[];

String asciiEncodedString = new String[germanBytes, StandardCharsets.US_ASCII];

assertNotEquals[asciiEncodedString, germanString];

Chuỗi này được mã hóa bằng US_ASCII mang lại cho chúng tôi giá trị “Entwickeln Sie mit Vergn?gen” khi được in vì nó không hiểu ký tự ü không phải ASCII

Nhưng khi chúng tôi chuyển đổi Chuỗi được mã hóa ASCII sử dụng tất cả các ký tự tiếng Anh sang UTF-8, chúng tôi sẽ nhận được cùng một chuỗi

String englishString = "Develop with pleasure";
byte[] englishBytes = englishString.getBytes[];

String asciiEncondedEnglishString = new String[englishBytes, StandardCharsets.US_ASCII];

assertEquals[asciiEncondedEnglishString, englishString];

Hãy xem điều gì sẽ xảy ra khi chúng ta sử dụng mã hóa UTF-8

3. Mã hóa với Core Java

Hãy bắt đầu với thư viện cốt lõi

Các chuỗi là bất biến trong Java, điều đó có nghĩa là chúng ta không thể thay đổi mã hóa ký tự Chuỗi. Để đạt được những gì chúng ta muốn, chúng ta cần sao chép các byte của Chuỗi và sau đó tạo một chuỗi mới với mã hóa mong muốn

Đầu tiên, chúng tôi lấy các byte Chuỗi, sau đó chúng tôi tạo một byte mới bằng cách sử dụng các byte đã truy xuất và bộ ký tự mong muốn

String rawString = "Entwickeln Sie mit Vergnügen";
byte[] bytes = rawString.getBytes[StandardCharsets.UTF_8];

String utf8EncodedString = new String[bytes, StandardCharsets.UTF_8];

assertEquals[rawString, utf8EncodedString];

4. Mã hóa với Java 7 StandardCharsets

Ngoài ra, chúng ta có thể sử dụng lớp StandardCharsets được giới thiệu trong Java 7 để mã hóa Chuỗi

Đầu tiên, chúng tôi sẽ giải mã Chuỗi thành byte và thứ hai, chúng tôi sẽ mã hóa Chuỗi thành UTF-8

String rawString = "Entwickeln Sie mit Vergnügen";
ByteBuffer buffer = StandardCharsets.UTF_8.encode[rawString]; 

String utf8EncodedString = StandardCharsets.UTF_8.decode[buffer].toString[];

assertEquals[rawString, utf8EncodedString];

5. Mã hóa với Commons-Codec

Bên cạnh việc sử dụng Java lõi, chúng ta có thể sử dụng Apache Commons Codec để đạt được kết quả tương tự

Apache Commons Codec là một gói tiện dụng chứa các bộ mã hóa và giải mã đơn giản cho các định dạng khác nhau

Đầu tiên, hãy bắt đầu với cấu hình dự án

Khi sử dụng Maven, chúng ta phải thêm phần phụ thuộc commons-codec vào pom của mình. xml


    commons-codec
    commons-codec
    1.14

Sau đó, trong trường hợp của chúng tôi, lớp thú vị nhất là StringUtils, cung cấp các phương thức để mã hóa Chuỗi

Sử dụng lớp này, việc nhận Chuỗi được mã hóa UTF-8 khá đơn giản

String rawString = "Entwickeln Sie mit Vergnügen"; 
byte[] bytes = StringUtils.getBytesUtf8[rawString];
 
String utf8EncodedString = StringUtils.newStringUtf8[bytes];

assertEquals[rawString, utf8EncodedString];

6. Phần kết luận

Mã hóa Chuỗi thành UTF-8 không khó, nhưng nó không trực quan. Bài viết này trình bày ba cách để thực hiện, sử dụng Java lõi hoặc Bộ giải mã Apache Commons

UTF-8 là một cách thông minh để mã hóa văn bản Unicode. Gần đây tôi đã đề cập đến nó một vài lần, nhưng bản thân tôi chưa viết blog về UTF-8. Đây đi

Vấn đề UTF-8 giải quyết

Bàn phím của Hoa Kỳ thường có thể tạo ra 101 ký hiệu, điều này cho thấy 101 ký hiệu là đủ cho hầu hết văn bản tiếng Anh. Bảy bit sẽ đủ để mã hóa các ký hiệu này vì 27 = 128 và đó là những gì ASCII làm. Nó đại diện cho mỗi ký tự có 8 bit vì máy tính hoạt động với các bit theo nhóm có kích thước là lũy thừa của 2, nhưng bit đầu tiên luôn bằng 0 vì không cần thiết. ASCII mở rộng sử dụng khoảng trống còn lại trong ASCII để mã hóa nhiều ký tự hơn

Tổng cộng 256 ký tự có thể phục vụ tốt cho một số người dùng, nhưng nó sẽ không bắt đầu cho phép bạn đại diện, chẳng hạn như tiếng Trung Quốc. Ban đầu, Unicode muốn sử dụng hai byte thay vì một byte để biểu thị các ký tự, điều này sẽ cho phép 216 = 65.536 khả năng, đủ để nắm bắt rất nhiều hệ thống chữ viết trên thế giới. Nhưng không phải tất cả, và do đó, Unicode đã mở rộng thành bốn byte

Nếu bạn lưu trữ văn bản tiếng Anh bằng cách sử dụng hai byte cho mỗi chữ cái, thì một nửa dung lượng sẽ bị lãng phí khi lưu trữ các số không. Và nếu bạn sử dụng bốn byte cho mỗi chữ cái, ba phần tư dung lượng sẽ bị lãng phí. Nếu không có một số loại mã hóa, mọi tệp chứa bài kiểm tra tiếng Anh sẽ lớn hơn gấp hai hoặc bốn lần so với mức cần thiết. Và không chỉ tiếng Anh, mà mọi ngôn ngữ có thể biểu diễn bằng ASCII

UTF-8 là một cách mã hóa Unicode để tệp văn bản ASCII tự mã hóa. Không lãng phí không gian, ngoài bit đầu tiên của mỗi byte ASCII không sử dụng. Và nếu tệp của bạn chủ yếu là văn bản ASCII với một vài ký tự không phải ASCII được thêm vào, thì các ký tự không phải ASCII chỉ làm cho tệp của bạn dài hơn một chút. Bạn không cần phải đột nhiên làm cho mọi ký tự chiếm dung lượng gấp đôi hoặc bốn lần chỉ vì bạn muốn sử dụng, chẳng hạn như ký hiệu Euro € [U+20AC]

UTF-8 làm điều đó như thế nào

Vì bit đầu tiên của ký tự ASCII được đặt thành 0, nên các byte có bit đầu tiên được đặt thành 1 không được sử dụng và có thể được sử dụng đặc biệt

Khi phần mềm đọc UTF-8 bắt gặp một byte bắt đầu bằng 1, nó sẽ đếm số 1 theo sau trước khi gặp 0. Ví dụ: trong một byte có dạng 110xxxxx, có một số 1 theo sau số 1 ban đầu. Gọi n là số các số 1 nằm giữa số 1 đầu tiên và số 0 đầu tiên. Các bit còn lại trong byte này và một số bit trong n byte tiếp theo sẽ đại diện cho một ký tự Unicode. Không cần n lớn hơn 3 vì những lý do chúng ta sẽ đề cập sau. Nghĩa là, phải mất tối đa bốn byte để biểu thị một ký tự Unicode bằng UTF-8

Vì vậy, một byte có dạng 110xxxxx cho biết năm bit đầu tiên của ký tự Unicode được lưu trữ ở cuối byte này và phần còn lại của các bit sẽ đến trong byte tiếp theo

Một byte có dạng 1110xxxx chứa bốn bit của ký tự Unicode và nói rằng phần còn lại của các bit sẽ đến trong hai byte tiếp theo

Một byte có dạng 11110xxx chứa ba bit của ký tự Unicode và nói rằng phần còn lại của các bit sẽ đến trong ba byte tiếp theo

Sau byte đầu tiên thông báo phần đầu của một ký tự trải rộng trên nhiều byte, các bit được lưu trữ theo byte có dạng 10xxxxxx. Vì các byte đầu tiên của chuỗi nhiều byte bắt đầu bằng hai bit 1, nên không có sự mơ hồ. một byte bắt đầu bằng 10 không thể đánh dấu sự bắt đầu của một chuỗi nhiều byte mới. Tức là, UTF-8 tự chấm câu

Vì vậy, chuỗi nhiều byte có một trong các dạng sau

    110xxxxx 10xxxxxx
    1110xxxx 10xxxxxx 10xxxxxx
    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Nếu bạn đếm các chữ x ở hàng dưới cùng thì có 21 chữ số. Vì vậy, sơ đồ này chỉ có thể biểu thị các số có tối đa 21 bit. Chúng ta không cần 32 bit sao?

Mặc dù một ký tự Unicode bề ngoài là một số 32 bit, nhưng thực tế phải mất tối đa 21 bit để mã hóa một ký tự Unicode vì những lý do được giải thích tại đây. Đây là lý do tại sao n, số 1 theo sau số 1 đầu tiên ở đầu chuỗi nhiều byte, chỉ cần là 1, 2 hoặc 3. Sơ đồ mã hóa UTF-8 có thể được mở rộng để cho phép n = 4, 5 hoặc 6, nhưng điều này là không cần thiết

Hiệu quả

UTF-8 cho phép bạn lấy một tệp ASCII thông thường và coi đó là tệp Unicode được mã hóa bằng UTF-8. Vì vậy, UTF-8 hiệu quả như ASCII về mặt không gian. Nhưng không phải về mặt thời gian. Nếu phần mềm biết rằng một tệp trên thực tế là ASCII, thì nó có thể lấy từng byte theo mệnh giá, không cần phải kiểm tra xem đó có phải là byte đầu tiên của chuỗi nhiều byte hay không

Và trong khi ASCII đơn giản là UTF-8 hợp pháp, ASCII mở rộng thì không. Vì vậy, các ký tự ASCII mở rộng giờ đây sẽ chiếm hai byte mà chúng từng lấy một byte. Bài đăng trước của tôi là về sự nhầm lẫn có thể xảy ra do phần mềm diễn giải tệp được mã hóa UTF-8 dưới dạng tệp ASCII mở rộng

Làm cách nào để chuyển đổi chuỗi thành UTF?

Để chuyển đổi Chuỗi thành UTF-8, chúng tôi sử dụng phương thức getBytes[] trong Java . Phương thức getBytes[] mã hóa một Chuỗi thành một chuỗi byte và trả về một mảng byte. trong đó charsetName là bộ ký tự cụ thể mà Chuỗi được mã hóa thành một mảng byte.

Có thể UTF

UTF-8 mở rộng bộ ký tự ASCII để sử dụng các điểm mã 8 bit, cho phép tối đa 256 ký tự khác nhau. Điều này có nghĩa là UTF-8 có thể đại diện cho tất cả các ký tự ASCII có thể in được, cũng như các ký tự không in được .

Cách mã hóa sang UTF

Làm cách nào để chuyển đổi chuỗi thành UTF-8 trong Python? .
string1 = "apple" string2 = "Preeti125" string3 = "12345" string4 = "pre@12"
chuỗi. mã hóa [mã hóa = 'UTF-8', lỗi = 'nghiêm ngặt']
# chuỗi unicode string = 'pythön. ' # mã hóa mặc định thành utf-8 string_utf = string. encode[] print['Phiên bản được mã hóa là. ', string_utf]

UTF là gì

UTF-8 là phương thức mã hóa ký tự Unicode . Điều này có nghĩa là UTF-8 lấy điểm mã cho một ký tự Unicode nhất định và dịch nó thành một chuỗi nhị phân. Nó cũng làm ngược lại, đọc các chữ số nhị phân và chuyển đổi chúng trở lại ký tự.

Chủ Đề