2014-05-21 17 views
14

Tôi đã từng chơi với một vài thư viện mã hóa JS (CryptoJS, SJCL) và phát hiện các vấn đề liên quan đến Blob/File APIs và "chuỗi nhị phân" JavaScript.Tạo Blob hoặc Tệp từ chuỗi nhị phân JavaScript thay đổi số byte?

Tôi nhận ra rằng mã hóa thậm chí không thực sự có liên quan, do đó, đây là một kịch bản được đơn giản hóa nhiều. Đơn giản chỉ cần đọc một tập tin trong việc sử dụng readAsBinaryString và sau đó tạo ra một Blob:

>>> reader.result 
"GIF89a����ÿÿÿÿÿÿ!þCreated with GIMP�,�������D�;" 
>>> reader.result.length 
56 
>>> typeof reader.result 
"string" 
>>> blob = new Blob([reader.result], {type: "image/gif"}) 
Blob { size=64, type="image/gif", constructor=function(), more...} 

tôi đã tạo ra một JSFiddle rằng sẽ cơ bản làm các việc trên: nó chỉ đơn giản là đọc bất kỳ tập tin tùy ý, tạo ra một blob từ nó, và kết quả đầu ra độ dài vs size: http://jsfiddle.net/6L82t/1/

Dường như, khi tạo Blob từ chuỗi "nhị phân (javascript)", một số thứ có mã hóa ký tự kết thúc sẽ làm tăng kết quả.

Nếu không sử dụng tệp nhị phân, bạn sẽ thấy rằng độ dài của Blob và chuỗi nhị phân gốc giống nhau.

Vì vậy, có điều gì đó sẽ xảy ra khi cố gắng tạo Blob/Tệp từ chuỗi Javascript không nguyên bản và tôi cần bất kỳ điều gì không xảy ra. Tôi nghĩ rằng nó có thể có một cái gì đó để làm với thực tế là các chuỗi JS là UTF-16?

Có một (có thể) có liên quan đến chủ đề ở đây: HTML5 File API read as text and binary

Tôi có cần để có thể lấy kết quả giải mã (UTF-16) và "chuyển đổi" họ sang UTF-8 trước khi đặt chúng trong một Blob/File ?

Làm việc với một người nào đó trong # html5 trên Freenode, chúng tôi xác định rằng nếu bạn đọc một ArrayBuffer trực tiếp và sau đó tạo blob từ đó bằng cách sử dụng một Uint8Array, các byte làm việc ra tốt. Bạn có thể thấy một câu đố về cơ bản là ở đây: http://jsfiddle.net/GH7pS/4/

Vấn đề là, ít nhất trong trường hợp của tôi, tôi sẽ kết thúc bằng chuỗi nhị phân và muốn tìm cách chuyển đổi trực tiếp thành Blob để tôi có thể sử dụng tải xuống html5 để cho phép người dùng nhấp để tải xuống blob trực tiếp.

Cảm ơn!

+1

Bạn nhận ra rằng bài viết của bạn [đã có một lịch sử sửa đổi toàn diện] (http://stackoverflow.com/posts/23795034/revisions), phải không? Bạn có thể nhận được dấu thời gian chính xác của bất kỳ lúc nào được đăng trên trang web SE bằng cách di chuột qua nó; hãy thử điều đó với "đã hỏi 2 giờ trước" bên trên tên của bạn. –

Trả lời

16

Dường như, khi tạo Blob từ chuỗi "nhị phân (javascript)", một thứ có mã hóa ký tự sẽ kết thúc bằng cách tạo kết quả.

Có. That post you read giải thích rõ cách thức một "chuỗi nhị phân" được cấu thành.

Các Blob constructor trái ngược không

  1. Hãy s là kết quả của việc chuyển đổi [chuỗi] để một chuỗi các Unicode characters bằng cách sử dụng thuật toán để làm như vậy trong WebIDL.
  2. Mã hóa s làm UTF-8 và nối thêm các byte kết quả vào [blob].

Chúng tôi xác định rằng nếu bạn đọc một ArrayBuffer trực tiếp và sau đó tạo ra các blob từ đó bằng cách đầu tiên sử dụng một Uint8Array, các byte làm việc ra tốt.

Vâng, đó là cách hoạt động của nó. Chỉ cần thực hiện mã hóa trên một mảng được đánh máy, nơi bạn xử lý các byte riêng lẻ, không phải trên một số chuỗi.

Vấn đề là, ít nhất là trong kịch bản của tôi, tôi sẽ kết thúc với một chuỗi nhị phân

Again: Cố gắng không để. binary strings are deprecated.

Tôi muốn tìm ra cách chuyển đổi trực tiếp chuỗi nhị phân thành Blob. Tôi có cần phải có thể lấy các kết quả đã được giải mã (UTF-16) và "chuyển đổi" chúng thành UTF-8 trước khi đưa chúng vào một tệp Blob/File không?

Không, tốt hơn đừng cố thực hiện bất kỳ chuyển đổi chuỗi nào. Thay vào đó, hãy xây dựng một Uint8Array (Uint8Array) cho các byte mà bạn muốn nhận từ chuỗi nhị phân.

này nên làm điều đó (chưa được kiểm tra):

var bytes = new Uint8Array(str.length); 
for (var i=0; i<str.length; i++) 
    bytes[i] = str.charCodeAt(i); 
+0

Điều đó hoàn toàn hiệu quả. Tôi đoán câu hỏi tiếp theo liên quan cụ thể đến CryptoJS - khi bạn giải mã nội dung và nhận "WordArray" của bạn, có cách nào để truy cập trực tiếp tới ArrayBuffer mà không cần chuyển đổi thành chuỗi và sau đó đặt nó vào Uint8Array để sử dụng cho blob? –

+1

Theo dõi: Có vẻ như ai đó đã làm điều gì đó không liên quan đến chuyển đổi chuỗi trước (hoạt động trên byte): https://groups.google.com/d/msg/crypto-js/TOb92tcJlU0/Eq7VZ5tpi- QJ Dường như công trình này hoạt động. Tuyệt vời! –

+0

Vâng, đó có thể là một câu hỏi riêng biệt tốt (được gắn thẻ [tag: cryptojs]). Tôi không biết họ có các kiểu dữ liệu riêng của họ, tôi phải tìm những thứ như vậy trong tài liệu của họ. – Bergi

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