2009-11-04 53 views
31

Cho một mảng byte biểu diễn văn bản trong một số mã hóa không xác định (thường là UTF-8 hoặc ISO-8859-1, nhưng không nhất thiết như vậy), cách tốt nhất để có được một đoán cho mã hóa có khả năng nhất được sử dụng (trong Java)?Đoán mã hóa của văn bản được biểu diễn dưới dạng byte [] trong Java

Worth chú ý:

  • Không thêm siêu dữ liệu có sẵn. Mảng byte theo nghĩa đen là đầu vào duy nhất có sẵn.
  • Thuật toán phát hiện rõ ràng sẽ không chính xác 100%. Nếu thuật toán chính xác hơn 80% các trường hợp đủ tốt.
+2

http://stackoverflow.com/questions/373081/ có thể giúp đỡ – Chris

Trả lời

28

Phương pháp sau đây giải quyết vấn đề bằng cách sử dụng juniversalchardet, là một cổng Java của thư viện phát hiện mã hóa của Mozilla.

public static String guessEncoding(byte[] bytes) { 
    String DEFAULT_ENCODING = "UTF-8"; 
    org.mozilla.universalchardet.UniversalDetector detector = 
     new org.mozilla.universalchardet.UniversalDetector(null); 
    detector.handleData(bytes, 0, bytes.length); 
    detector.dataEnd(); 
    String encoding = detector.getDetectedCharset(); 
    detector.reset(); 
    if (encoding == null) { 
     encoding = DEFAULT_ENCODING; 
    } 
    return encoding; 
} 

Đoạn mã trên đã được kiểm tra và hoạt động theo ý muốn. Chỉ cần thêm juniversalchardet-1.0.3.jar vào đường dẫn lớp.

Tôi đã thử nghiệm cả hai juniversalchardetjchardet. Ấn tượng chung của tôi là juniversalchardet cung cấp độ chính xác phát hiện tốt hơn và API đẹp hơn của hai thư viện.

+0

Yêu cầu dự án của tôi là nếu dữ liệu không có trong utf8 (sau khi phát hiện) thì chuyển nó thành utf8, làm thế nào để làm điều này? –

+0

@coding_idiot sử dụng mã hóa "được đoán" để chuyển đổi thành Chuỗi sau đó nhận được byte utf-8: 'Chuỗi mới (byte, guessedEncoding) .getBytes (" utf-8 ")'. –

+0

Bây giờ dự án là trên [github] (https://github.com/albfernandez/juniversalchardet) – bigspawn

0

Check-out jchardet

+7

Vui lòng giải thích - tại sao bạn coi jchardet là thư viện tốt nhất? – knorv

+0

@chi cách chuyển đổi thành utf8 nếu mã hóa không phải là utf8. –

-1

Nên thứ đã có sẵn

google tìm kiếm bật lên icu4j

hoặc

http://jchardet.sourceforge.net/

+2

Tôi biết cách sử dụng Google, nhưng câu hỏi đặc biệt yêu cầu "cách tốt nhất [..]" là gì. Vì vậy, đó là tốt nhất, icu4j, jchardet hoặc một số thư viện khác? – knorv

1

câu trả lời Chí dường như hứa hẹn nhất để sử dụng thực sự. Tôi chỉ muốn nói thêm rằng, theo Joel Spolsky, Internet Explorer sử dụng một thuật toán đoán tần số dựa trên thời kỳ đó:

http://www.joelonsoftware.com/articles/Unicode.html

Nói đại khái, tất cả các giả định-to-be-văn bản được sao chép, và phân tích cú pháp trong mọi mã hóa có thể tưởng tượng được. Cho dù phân tích cú pháp nào phù hợp với cấu hình tần suất từ ​​(và chữ cái) trung bình của ngôn ngữ tốt nhất, hãy thắng. Tôi không thể nhanh chóng nhìn thấy nếu jchardet sử dụng cùng một cách tiếp cận, vì vậy tôi nghĩ rằng tôi muốn đề cập đến điều này chỉ trong trường hợp.

-1

Nếu không có chỉ báo mã hóa, bạn sẽ không bao giờ biết chắc chắn. Tuy nhiên, bạn có thể thực hiện một số dự đoán thông minh. Xem câu trả lời của tôi cho câu hỏi này,

How to determine if a String contains invalid encoded characters

Sử dụng các phương pháp validUTF8(). Nếu nó trả về true, hãy coi nó là UTF8, nếu không là Latin-1.

+0

Còn những trường hợp không phải là UTF-8 thì sao? – knorv

+0

Nếu nó không phải là UTF-8, một cách mù quáng gọi nó là Latin-1 không phải là một ý tưởng tốt. Nó sẽ là tốt hơn để sử dụng ICU, jchardet, hoặc một trong những công cụ khác được liệt kê trên trang này để thực hiện một đoán thông minh. –

3

Dưới đây là yêu thích của tôi: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

Nó hoạt động như thế này:

  • Nếu có một UTF-8 hoặc UTF-16 BOM, trở về mã hóa đó.
  • Nếu không có byte nào có bộ bit đặt hàng cao, trả về ASCII (hoặc bạn có thể buộc nó trả lại mã hóa 8 bit mặc định thay thế).
  • Nếu có các byte có bộ bit cao nhưng chúng được sắp xếp theo đúng mẫu cho UTF-8, trả về UTF-8.
  • Nếu không, hãy trả lại mã hóa mặc định nền tảng (ví dụ: windows-1252 trên hệ thống Windows tiếng Anh).

Nghe có vẻ quá đơn giản, nhưng trong công việc hàng ngày của tôi, nó chính xác hơn 90%.

4

Ngoài ra còn có Apache Tika - a content analysis toolkit. Nó có thể đoán loại mime, và nó có thể đoán mã hóa. Thông thường, dự đoán là chính xác với xác suất rất cao.

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