Biên mã kí tự

Biên mã kí tự (tiếng Anh: character encoding; còn được gọi là mã hoá kí tự (động từ), bảng mã hay bộ mã kí tự (danh từ)) là quá trình gán các số cho các kí tự đồ hoạ, nhất là những con chữ trong ngôn ngữ của con người, cho phép chúng có thể được lưu trữ, truyền đi và chuyển đổi bằng các máy tính số. Các giá trị dạng số tạo thành một biên mã kí tự được gọi là các "điểm mã" ("code point") và khi gộp lại thì gồm có một "không gian mã" ("code space"), một "trang mã" ("code page") hoặc một "ánh xạ kí tự".
Các mã kí tự thời kì đầu gắn liền với điện báo điện tử hoặc điện báo quang chỉ có thể thể hiện một tập con trong số các kí tự được dùng trong ngôn ngữ viết, đôi khi bị giới hạn thành chỉ còn các chữ cái in hoa, con số và một số dấu câu. Việc thể hiện dữ liệu dưới dạng kĩ thuật số trong máy tính hiện đại với chi phí thấp đã cho phép thêm nhiều mã kí tự đồ sộ hơn, chẳng hạn như Unicode, thể hiện phần lớn các kí tự trong nhiều ngôn ngữ viết. Biên mã kí tự sử dụng các tiêu chuận được quốc tế chấp nhận cho phép sự trao đổi văn bản toàn cầu dưới dạng điện tử.
Lịch sử.
Lịch sử của mã kí tự gắn liền với nhu cầu ngày càng tăng của thông tin biểu tượng dựa trên kí tự qua trung gian là máy tính ở khoảng cách xa, sử dụng các phương tiện điện tử từng được coi là mới mẻ. Các loại mã sớm nhất được dựa trên các hệ thống chuyển vị ("cyphering") và biên mã thủ công được viết tay, chẳng hạn như chuyển vị Bacon, Braille và bảng mã kí tự tiếng Trung bốn chữ số được dùng cho Trung văn điện mã (Hans Schjellerup, 1869). Với việc áp dụng các kĩ thuật điện-cơ và điện tử, những loại mã sớm nhất này đã được điều chỉnh cho phù hợp với những khả năng và hạn chế của các cỗ máy thời kì đầu. Loại mã kí tự được truyền bằng điện được biết đến sớm nhất, mã Morse, được giới thiệu vào những năm 1840, sử dụng một hệ thống bốn "biểu tượng" (tín hiệu ngắn, tín hiệu dài, khoảng trắng ngắn và khoảng trắng dài) để sinh mã với độ dài biến thiên. Dù nhiều lần được sử dụng vào mục đích thương mại bằng máy móc, mã Morse thường được dùng như một loại mã thủ công, được viết bằng tay thông qua một phím điện báo, có thể được giải mã bằng tai và vẫn còn được dùng trong phát thanh nghiệp dư và hàng không. Phần lớn các loại mã có độ dài mỗi kí tự cố định hoặc là chuỗi có độ dài biến thiên của các mã có độ dài cố định (v.d.Unicode).
Một số ví dụ về các hệ biên mã kí tự phổ biến là mã Morse, mã Baudot, Mã chuẩn Hoa Kỳ dùng cho Trao đổi Thông tin (ASCII) và Unicode. Unicode, một hệ biên mã được xác định rõ ràng và dễ mở rộng, đã thế chỗ hầu hết biên mã kí tự sớm hơn nó.
Mã Baudot, một biên mã năm bit, được Émile Baudot tạo ra vào năm 1870, được cấp bằng sáng chế năm 1874, được Donald Murray chỉnh sửa năm 1901, và được CCITT tiêu chuẩn hoá thành Bảng chữ cái Điện báo Quốc tế Số 2 ("International Telegraph Alphabet No. 2" hay ITA2) vào năm 1930. Cái tên "baudot" đã bị áp dụng một cách sai lầm vào ITA2 và nhiều biến thể khác. ITA2 đã tồn tại nhiều thiếu sót và thường được "cải tiến" bởi nhiều nhà sản xuất thiết bị, đôi khi gây ra vấn đề về tương thích. Năm 1959, quân đội Mĩ đã định nghĩa ra mã Fieldata, một loại mã sáu hoặc bảy bit, được Quân đoàn Truyền tin Hoa Kỳ giới thiệu. Dù Fieldata đã đề cập đến nhiều vấn đề của thời đó (v.d. chữ và số được sắp xếp để máy đối chiếu), Fieldata đã không đạt được mục tiêu của mình và không tồn tại được lâu. Vào năm 1963, mã ASCII (American Standard Code for Information Interchange; "Mã chuẩn Hoa Kỳ dùng cho Trao đổi Thông tin") lần đầu tiên được ra mắt (X3.4-1963) bởi hội đồng ASCII (gồm ít nhất một thành viên của hội đồng Fieldata, W. F. Leubbert), giải quyết được phần lớn những khuyết điểm của Fieldata, bằng cách sử dụng một dạng mã ngắn gọn hơn. Nhiều sự thay đổi là khó thấy, chẳng hạn như tập kí tự sắp xếp được trong những khoảng số nhất định. ASCII63 đã trở nên thành công, được chấp nhận rộng rãi trong công nghiệp, và với những bản phát hành tiếp đó của mã ASCII 1967 (bổ sung thêm chữ in thường và sửa một số vấn đề về "mã điều khiển") ASCII67 đã được chấp nhận một cách tương đối rộng rãi. Bản chất hướng-Mĩ của ASCII67 đã phần nào được giải quyết trong chuẩn ECMA-6 Châu Âu.
Herman Hollerith đã phát minh ra biên mã dữ liệu bằng thẻ đục lỗ vào cuối thế kỉ 19 để phân tích dữ liệu điều tra dân số. Ban đầu, mỗi vị trí của lỗ đại diện cho một phần tử dữ liệu khác nhau, nhưng về sau, thông tin dạng số được biên mã bằng cách đánh số những hàng bên dưới từ 0 đến 9, với mỗi chỗ đục trong một cột đại diện cho số hàng của nó. Dữ liệu chữ cái về sau được biên mã bằng cách cho phép đục nhiều hơn một lỗ mỗi cột. Các máy lập bảng ("tabulating machine") điện cơ biểu diễn ngày tháng bên trong máy bằng thời gian của các xung nhịp so với chuyển động của thẻ chạy trong máy. Khi IBM chuyển sang xử lí điện tử, bắt đầu từ mẫu sản phẩm IBM 603 Electronic Multiplier, nó đã sử dụng nhiều loại biên mã nhị phân khác nhau gắn với mã thẻ đục lỗ.
Số thập phân được mã hoá nhị phân của IBM ("Binary Coded Decimal", viết tắt là BCD) là một sơ đồ biên mã sáu bit đã được IBM sử dụng từ những năm 1953 trong các mẫu máy tính 702 và 704 của công ty, và trong các dòng máy 7000 Series và 1400 series về sau, cũng như trong các thiết bị ngoại vi liên quan. Vì mã thẻ đục lỗ thời đó chỉ sử dụng các chữ số được cho phép, các chữ cái tiếng Anh viết hoa và một và kí tự đặc biệt, 6 bit là đủ dùng. BCD đã mở rộng biên mã dạng số bốn bit đơn giản hiện có để bao gồm bảng chữ cái và các kí tự đặc biệt, dễ dàng ánh xạ nó với biên mã thẻ đục lỗ vốn đang được sử dụng rộng rãi. Mã của IBM được dùng chủ yếu với các thiết bị của IBM; các nhà cung cấp máy tính cùng thời có các loại mã kí tự riêng, thường là sáu bit, nhưng thường có khả năng đọc được các loại băng do thiết bị của IBM tạo ra. BCD là tiền thân của EBCDIC (Extended Binary Coded Decimal Interchange Code; "Mã Trao đổi Thập phân Được mã hoá Nhị phân Mở rộng)," một sơ đồ biên mã tám bit được phát triển vào năm 1963 cho máy IBM System/360 với một tập kí tự lớn hơn, bao gồm cả các chữ cái in thường.
Các giới hạn của những tập kí tự này sớm trở nên rõ ràng, và một số phương pháp dành riêng cho vấn đề này đã được phát triển để mở rộng chúng. Nhu cầu hỗ trợ thêm các hệ chữ viết của các ngôn ngữ khác nhau, bao gồm họ chữ CJK trong các chữ viết Đông Á, đặt ra yêu cầu hỗ trợ một lượng kí tự lớn hơn nhiều và một cách tiếp cận có hệ thống về biên mã kí tự thay cho các cách tiếp cận đặc biệt trước đây.
Trong quá trình phát triển các biên mã kí tự chung có thể hoán đổi được cho nhau, các nhà nghiên cứu vào những năm 1980 đã gặp phải tình thế tiến thoái lưỡng nan rằng, một mặt, dường như cần phải thêm nhiều bit hơn để có thể chứa được các kí tự bổ sung; nhưng mặt khác, đối với những người dùng một tập kí tự tương đối nhỏ trong bảng chữ cái La-tinh (chiếm phần lớn số người dùng máy tính) thì những bit bổ sung đó lại là một sự lãng phí rất lớn tài nguyên máy tính vốn đã đắt đỏ và khan hiếm vào thời điểm đó (vì chúng sẽ luôn bị bỏ đi đối với những người dùng này). Vào năm 1985, ổ cứng của một máy tính tầm trung chỉ có thể lưu trữ khoảng 10 megabyte, và có giá khoảng 250 USD trên thị trường bán sỉ (và thường cao hơn nhiều nếu được mua riêng tại cửa hàng bán lẻ), vậy nên vào thời đó mỗi bit đều được tận dụng triệt để.
Giải pháp thoả hiệp cuối cùng cũng được tìm ra và phát triển vào Unicode, đó là bỏ đi giả định (có từ thời mã điện báo) rằng một kí tự chỉ luôn tương ứng trực tiếp với một chuỗi bit cụ thể. Thay vào đó, các kí tự đầu tiên sẽ được ánh xạ vào một kiểu biểu diễn trung gian dùng chung dưới dùng các con số trừu tượng được gọi là điểm mã. Các điểm mã sau đó sẽ được biểu diễn theo nhiều cách và với những số bit mỗi kí tự mặc định khác nhau (đơn vị mã) phụ thuộc vào ngữ cảnh. Để biên mã các điểm mã cao hơn chiều dài của đơn vị mã , chẳng hạn từ 256 trở lên đối với đơn vị 8 bit, giải pháp là triển khai biên mã với chiều rộng biến thiên ("variable-width encoding"), nơi mà một chuỗi thoát sẽ báo hiệu ràng các bit theo sau nên được phân tích thành một điểm mã cao hơn.
Thuật ngữ.
Danh mục kí tự ("character repertoire") hay "tập kí tự trừu tượng" là một tập trừu tượng của hơn một triệu kí tự được tìm thấy trong nhiều hệ chữ viết bao gồm chữ La tinh, Kirin, Trung Quốc, Triều Tiên, Nhật Bản, Do Thái và Aram.
Các biểu tượng khác chẳng hạn như kí hiệu âm nhạc cũng được cho vào danh mục kí tự. Cả tiêu chuẩn Unicode và GB18030 đều có một danh mục kí tự. Khi những kí tự mới được thêm vào một tiêu chuẩn, các tiêu chuẩn khác cũng sẽ thêm các kí tự đó vào nhằm duy trì sự nhất quán.
Kích cỡ đơn vị mã tương đương với số lượng bit cho mỗi biên mã cụ thể:
"Ví dụ về đơn vị mã:" Xét một xâu gồm các chữ cái "abc" theo sau bởi kí tự (được biểu diễn bằng 1 char32_t, 2 char16_t hoặc 4 char8_t). Xâu đó chứa:
Theo quy ước, mỗi kí tự trong Unicode được kí hiệu bắt đầu bằng 'U+' theo sau là giá trị điểm mã theo hệ thập lục phân. Khoảng giá trị điểm mã hợp lệ trong Unicode tiêu chuẩn là từ U+0000 đến U+10FFFF, gồm các hai giá trị trên, được chia thành 17 mặt phẳng, được đánh dấu bằng số từ 0 đến 16. Các kí tự trong khoảng từ U+0000 đến U+FFFF nằm trong mặt phẳng 0, được gọi là Mặt phẳng Đa ngữ Cơ bản ("Basic Multilingual Plane" hay BMP). Mặt phẳng này chứa những kí tự thông dụng nhất. Các kí tự trong khoảng từ U+10000 đến U+10FFFF trong các mặt phẳng khác được gọi là các kí tự bổ sung.
Bảng sau đây là một số ví dụ về giá trị điểm mã:
Một điểm mã được biểu diễn bằng một chuỗi các đơn vị mã. Sự ánh xạ được định nghĩa bởi biên mã. Cho nên, số lượng đơn vị mã cần thiết để biểu diễn một điểm mã phụ thuộc vào biên mã:
Mô hình biên mã Unicode.
Unicode và các tiêu chuẩn song hành của nó, Tập Kí tự Toàn Cầu ("Universal Character Set") ISO/IEC 10646, cùng tạo nên một biên mã kí tự hiện đại và thống nhất. Thay vì ánh xạ các kí tự trực tiếp thành các octet, chúng lại định nghĩa riêng biệt những kí tự nào có sẵn, số tự nhiên tương ứng (điểm mã), cách những con số kia được biên mã thành một loạt các số tự nhiên với kích cỡ cố định (đơn vị mã) và cuối cùng là cách các đơn vị trên được biên mã dưới dạng một luồng các octet. Mục đích của việc phân tách này là để thiết lập nên một tập hợp phổ quát các kí tự có thể được biên mã theo nhiều cách khác nhau. Việc biểu diễn mô hình này một cách đúng đắn đòi hỏi các thuật ngữ chính xác và cụ thể hơn "tập kí tự" và "biên mã kí tự". Các thuật ngữ được sử dụng trong mô hình hiện đại như sau:
Một danh mục kí tự là một tập hợp đầy đủ các kí tự trừu tượng mà một hệ thống hỗ trợ. Danh mục có thể được coi là "đóng", tức là không được phép thêm bớt nếu chưa tạo ra một tiêu chuẩn mới (như là trường hợp của ASCII và phần lớn các chuẩn ISO-8859), hoặc nó có thể được coi là "mở," tức là cho phép thêm bớt (như trường hợp của Unicode và ở một mức độ nào đó là các trang mã Windows). Các kí tự trong một danh mục cụ thể phản ánh các quyết định được đưa ra về các chia các hệ chữ viết thành các đơn vị thông tin cơ bạn. Các biến thể cơ bản của bảng chữ cái Latinh, Hy Lạp và Kirin có thể được tách ra thành các chữ cái, chữ số, dấu câu và một số "kí tự đặc biệt" chẳng hạn như dấu cách; tất cả chúng đều có thể được sắp xếp thành các chuỗi thẳng hàng đơn giản và được hiển thị theo cùng thứ tự đọc. Nhưng kể cả với những bảng chữ cái trên thì các dấu phụ vẫn gây ra sự phức tạp: chúng có thể được xem như một phần của một kí tự chứa một chữ cái và dấu phụ (được gọi là kí tự dựng sẵn), hoặc là các kí tự khác nhau. Cách thứ nhất cho phép một hệ thống xử lí hệ thống văn bản đơn giản hơn nhiều nhưng cách thứ hai sẽ cho phép việc sử dụng bất kì tổ hợp chữ cái – dấu phụ nào trong văn bản. Chữ ghép cũng gây ra vấn đề tương tự. Các hệ chữ viết khác, chẳng hạn như Ả Rập và Do Thái, được biễu diễn bằng một danh mục kí tự phức tạp hơn để phù hợp với những như văn bản song hướng và các con chữ được nối với nhau theo những cách khác nhau trong những tình huống khác nhau.
Một tập kí tự được mã hoá ("coded character set" hay CCS) là một hàm ánh xạ các kí tự sang các điểm mã (mỗi điểm mã đại diện cho một kí tự). Ví dụ, trong một danh mục cụ thể, chữ cái "A" hoa trong bảng chữ cái Latinh có thể được biểu diễn bằng điểm mã 65, kí tự "B" là 66, vân vân. Nhiều tập kí tự được mã hoá có thể dùng chung một danh mục; ví dụ ISO/IEC 8859-1,các trang mã 037 và 500 của IBM đều cùng bao phủ cùng một danh mục nhưng lại ánh xạ chúng sang các điểm mã khác nhau.
Một dạng biên mã kí tự ("character encoding form" hay CEF) là một ánh xạ từ các điểm mã tới các "đơn vị mã" nhằm tạo điều kiện lưu trữ trong một hệ thống biểu diễn các số dưới dạng các chuỗi bit với độ dài cố định (bất kì hệ thống máy tính nào trên thực tế), Ví dụ, một hệ thống lưu trữ thông tin số học bằng các đơn vị 16 bit chỉ có thể biểu diễn một cách trực tiếp các điểm mã từ 0 đến 65535 trong mỗi đơn vị, còn những điểm mã lớn hơn (chẳng hạn từ 65536 đến 1.4 triệu) có thể được biểu diễn bằng nhiều đơn vị 16 bit. Sự tương ứng này là do CEF định nghĩa.
Tiếp theo, một sơ đồ biên mã kí tự ("character encoding scheme" hay CES) là một ánh xạ từ các điểm mã tới một "chuỗi các octet" nhằm tạo điều kiện lưu trữ trên những hệ thống tệp dựa trên octet hoặc truyền phát qua một mạng dựa trên octet. Một số sơ đồ biên mã kí tự đơn giản gồm có UTF-8, UTF-16BE, UTF-32BE, UTF-16LE or UTF-32LE; các sơ đồ biên mã kí tự phức hợp, chẳng hạn như UTF-16, UTF-32 và ISO/IEC 2022, chuyển qua lại giữa một số sơ đồ đơn giản bằng cách sử dụng các dấu thứ tự byte (BOM) hoặc chuỗi thoát; các sơ đồ nén thì cố gắng giảm bớt số byte sử dụng mỗi đơn vị mã (ví dụ như SCSU, BOCU, và Punycode).
Mặc dù UTF-32BE là một sơ đồ biên mã đơn giản hơn, phần lớn hệ thống làm việc với Unicode thường sử dụng UTF-8 – tương thích ngược với ASCII độ dài cố định và ánh xạ các điểm mã Unicode tới các chuỗi octet với độ dài biến thiên, hoặc UTF-16BE – tương thích ngược với UCS-2BE độ dài cố định và ánh xạ các điểm mã Unicode tới các chuỗi từ 16 bit với độ dài biến thiên. Xem bài so sánh các biên mã Unicode để biết thêm chi tiết.
Cuối cùng là những giao thức cấp cao cung cấp thông tin bổ sung để lựa chọn một biến thể kí tự Unicode nhất định, đặc biệt khi có các biến thể khu vực khác nhau mà trong Unicode lại là cùng một kí tự. Một ví dụ là thuộc tính codice_1 trong XML.
Mô hình Unicode sử dụng thuật ngữ ánh xạ kí tự đối với các hệ thống cũ gán trực tiếp một chuỗi kí tự thành một chuỗi byte, bao phủ tất cả các lớp CCS, CEF và CES.
Tập kí tự, ánh xạ kí tự và trang mã.
Trước đây, các thuật ngữ "biên mã kí tự", "ánh xạ kí tự", "tập kí tự" và "trang mã" từng là từ đồng nghĩa trong khoa học máy tính, vì một tiêu chuẩn sẽ đồng thời chỉ định một danh mục kí tự và cách chúng được biên mã thành một luồng các đơn vị mã – thường là một kí tự mỗi đơn vị mã. Tuy nhiên, ngày nay, các thuật ngữ này có ý nghĩa riêng dù liên quan đến nhau, nhờ vào những nỗ lực của các cơ quan tiêu chuẩn trong việc sử dụng các thuật ngữ chuẩn xác khi viết về và thống nhất nhiều hệ biên mã. Kể cả như vậy, các thuật ngữ vẫn được sử dụng thay cho nhau, với "tập kí tự" phổ biến hơn cả.
Một "trang mã" thường được hiểu là một biên mã hướng byte nhưng liên quan đến đối với một số bộ biên mã (bao phủ các hệ chữ viết khác nhau), nơi nhiều kí tự dùng cùng mã trong hầu hết tất cả các trang mã đó. Những bộ trang mã nổi tiếng là "Windows" (dựa trên Windows-1252) và "IBM"/"DOS" (dựa trên trang mã 437),xem bài trang mã Windows để biết chi tiết. Phần lớn các biên mã được xem là trang mã là các biên mã một byte (nhưng hãy xem bài octet về kích cỡ byte.)
Kiến trúc Biểu diễn Dữ liệu Kí Tự của IBM ("Character Data Representation Architecture" hay CDRA) chỉ định các thực thể với các mã định danh tập kí tự được mã hoá (CCSID), mỗi thực thể đó được gọi là một "charset", "tập kí tự", "trang mã", hay "CHARMAP".
Thuật ngữ "trang mã" không xuất hiện trong Unix hoặc Linux vì "charmap" ("ánh xạ kí tự") được dùng nhiều hơn, thường là trong ngữ cảnh rộng hơn của khu vực (locale).
Ngược lại với một "tập kí tự được mã hoá", một "biên mã kí tự" là một ánh xạ từ các kí tự trừu tượng tới các từ mã (code word). Một "tập kí tự" theo cách nói trong HTTP (và MIME) giống với một biên mã kí tự (nhưng khác với một CCS).
"Biên mã kế thừa" là một thuật ngữ thỉnh thoảng được dùng để chỉ những biên mã kí tự cũ, nhưng với ý nghĩa mơ hồ. Nó thường được dùng khi nói về việc Unicode hoá, khi đó nó đề cập đến những biên mã không bao phủ tất cả các điểm mã Unicode, hoặc tổng quát hơn, sử dụng một danh mục kí tự hơi khác: vài điểm mã biểu diễn một kí tự Unicode, hoặc ngược lại (ví dụ như trang mã 437). Một số nguồn coi một biên mã là "kế thừa" chỉ bởi vì nó có trước Unicode. Tất cả các trang mã Windows thường được xem là kế thừa, bởi vì chúng vừa xuất hiện trước Unicode, vừa không thể biểu diễn tất cả 221 điểm mã có thể có của Unicode.
Biên dịch biên mã kí tự.
Vì có nhiều phương pháp biên mã kí tự đang được sử dụng (và nhu cầu tương thích ngược với phần dữ liệu được lưu trữ), nhiều chương trình máy tính đã được phát triển để biên dịch dữ liệu giữa các sơ đồ biên mã với nhau – một dạng chuyển mã ("transcoding"). Một số chương trình được liệt kê dưới đây.
Đa nền tảng:
Tương tự Unix: 
Windows: