2012-11-22 57 views
12

Tôi đang cố gắng chuyển đổi chuỗi mã hóa ISO 8859-1 thành UTF-8.golang chuyển đổi iso8859-1 thành utf8

Chức năng sau đây hoạt động với thử nghiệm của tôi có chứa dấu âm tiếng Đức, nhưng tôi không chắc chắn mã hóa nguồn rune (b) cast giả định. Nó có giả định một loại mã hóa mặc định hay không, ví dụ: ISO8859-1 hoặc là có cách nào để nói cho nó những gì mã hóa để sử dụng?

func toUtf8(iso8859_1_buf []byte) string { 
    var buf = bytes.NewBuffer(make([]byte, len(iso8859_1_buf)*4)) 
    for _, b := range(iso8859_1_buf) { 
     r := rune(b) 
     buf.WriteRune(r) 
    } 
    return string(buf.Bytes()) 
} 
+1

Nhân tiện, bạn có nghĩa là iso8859-1, phải không? – ANisus

+0

có, xin lỗi về sự nhầm lẫn, tôi đã chỉnh sửa nó. – zeroc8

Trả lời

12

rune là một bí danh cho int32, và khi nói đến mã hóa, một rune được giả định là có giá trị ký tự Unicode (điểm code). Vì vậy, giá trị b trong rune(b) phải là giá trị unicode. Đối với 0x00 - 0xFF, giá trị này giống với Latin-1, vì vậy bạn không phải lo lắng về nó.

Sau đó, bạn cần phải mã hóa các rune thành UTF8. Nhưng mã hóa này đơn giản được thực hiện bằng cách chuyển đổi một số []rune thành string.

Đây là một ví dụ về chức năng của bạn mà không sử dụng gói byte:

func toUtf8(iso8859_1_buf []byte) string { 
    buf := make([]rune, len(iso8859_1_buf)) 
    for i, b := range iso8859_1_buf { 
     buf[i] = rune(b) 
    } 
    return string(buf) 
} 
+0

Tôi nghĩ chỉ có giá trị lên đến 0x7f là giống hệt nhau, cảm ơn vì đã chỉ ra điều đó. – zeroc8

+2

Các giá trị trong Unicode và Latin-1 là giống nhau (Latin-1 có thể được coi là tập con Unicode 0x00 - 0xFF). Nhưng khi bạn lưu trữ giá trị, Latin-1 chỉ sử dụng 1 byte (ví dụ '0x41') trong khi Unicode sử dụng 4 byte (ví dụ:' 0x00000041'). Điều có thể gây nhầm lẫn là mã hóa UTF-8 trong đó chỉ 0x00 - 0x7F được mã hóa theo cùng cách như Latin-1, sử dụng một byte đơn. – ANisus

+0

Điểm mã UTF-8 không tồn tại. Bạn có nghĩa là các đơn vị mã UTF-8 không? –

2

Hiệu quả của

r := rune(expression) 

là:

  • Khai báo biến r với loại rune (bí danh cho int32).
  • Khởi tạo biến số r với giá trị expresion.

Không có (tái) mã hóa có liên quan và nói cái nào nên được sử dụng tùy chọn chỉ có thể bằng cách viết/xử lý một cách rõ ràng mã hóa lại mã. May mắn thay, trong trường hợp này không cần mã hóa (re), Unicode kết hợp các mã của ISO 8859-1 theo cách tương đương với ASCII. (Nếu tôi đã kiểm tra chính xác here)

+0

Reencoding là cần thiết. Các chữ cái như ö không được mã hóa theo cùng một cách. Nếu bạn có chuỗi byte 'latin1 = [] byte {0x52, 0xE4, 0x76}', nó sẽ không chuyển đổi tốt thành chuỗi. (Nó nói * Räv * trong tiếng Latin-1) – ANisus

+2

Nhưng 0xE4 thực sự là 'ä', không phải' ö' trong ISO 8859-1: http://en.wikipedia.org/wiki/ISO/IEC_8859-1#Codepage_layout. Kiểm tra tại đây: http://play.golang.org/p/s4TfzJUa7m – zzzz

+0

Ah, tôi nghĩ tôi đã hiểu lầm. Đúng là không cần mã hóa lại giữa Latin-1 và Unicode. Có, trình tự byte cho biết Räv – ANisus

Các vấn đề liên quan