Làm thế nào để bạn nén các chuỗi ASCII thành ít byte hơn?


12

Tôi đang làm việc với một thiết bị nhúng với một giao thức duy nhất gửi tin nhắn đến các thiết bị khác và tôi đang tạo một ứng dụng phân tích các gói đã gửi. Mỗi gói mang 8 byte. Giao thức được định nghĩa là nơi byte đầu tiên là tiêu đề và 7 byte còn lại là dữ liệu.

Họ đang cố gắng vượt qua một chuỗi ID cụ thể nhưng chuỗi ID dài 8 ký tự (ASCII) để nó không vừa với 7 byte.

Điều mà đồng nghiệp của tôi nói với tôi là họ sẽ biến 8 byte ascii của chuỗi gốc thành số nguyên (thập phân) và gửi cho tôi 4 byte của chuỗi đó. Họ nói với tôi rằng tôi sẽ có thể có được chuỗi gốc từ 4 byte. Tôi đang có một thời gian khó khăn trong đầu của tôi về điều này.

Vì vậy, nếu bạn có một chuỗi ID như "IO123456", đó là 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36 trong ASCII .. Làm thế nào bạn có thể nén chuỗi đó thành 4 byte bằng cách biến nó thành số nguyên và tôi có thể lấy chuỗi gốc từ nó ? Tôi đang thiếu một cái gì đó hoặc là đồng nghiệp của tôi nhầm? Tôi hiểu đây là một câu hỏi thực sự hấp dẫn nhưng điều này thực sự không có ý nghĩa gì với tôi.


1
Mỗi ký tự ASCII chỉ mất 7 bit, do đó, một chuỗi có 8 ký tự ASCII thực sự có thể được lưu trữ trong 8 * 7 bit - 7 byte.
luiscubal

Câu trả lời:


17

ID có luôn ở dạng: IO123456 không? Điều mà đồng nghiệp của bạn có thể có nghĩa là anh ta chỉ gửi phần số, phù hợp dễ dàng trong 4 byte bỏ qua phần "IO".


1
Đây chính là nó. Hai byte đầu tiên luôn ở dạng chữ cái và phần còn lại là số, vì vậy nó có thể dễ dàng khớp với 4 byte như bạn đã nói. Mặc dù tôi không biết số lượng 4 byte tùy ý đến từ đâu, vì 999999 trong hex là F423F nên nhiều nhất là 3 byte ..
l46kok

5
@ l46kok: Số nguyên 3 byte (24 bit) rất hiếm, vì vậy có thể dễ dàng hơn để họ gửi nó dưới dạng số nguyên 32 bit (4 byte). Tôi sẽ không hoàn toàn ngạc nhiên nếu bạn nhận được nó trong biểu diễn gốc (thứ tự byte) của thiết bị nhúng.
Bart van Ingen Schenau

16

Nếu hai ký tự đầu tiên không phải là hằng số (nhưng luôn là các chữ cái) và sáu ký tự còn lại luôn là các số, một chuỗi như "IO123456" có thể được đóng gói thành 5 byte bằng cách chuyển đổi các số thành định dạng thập phân được mã hóa nhị phân (BCD):

IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
             |    |      \   /     \   /     \   /
            0x49 0x4f     0x12      0x34      0x56

Nếu có một bộ định danh giới hạn có thể có (hai chữ cái đầu tiên), bạn có thể mã hóa chúng thành một số và gửi nó thay vào đó (miễn là không có quá 256 kết hợp), ví dụ:

IO -> 0x00
RD -> 0x01
WT -> 0x02
   ...
AB -> 0x10
   ...
ZZ -> 0xff

để chuỗi gốc được đóng gói thành 4 byte mà không mất thông tin:

IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
              \    /     \   /     \   /     \   /
               0x00       0x12      0x34      0x56

Tất nhiên quá trình này cũng có thể được đảo ngược để có được chuỗi ID gốc.


3

Nếu chuỗi có thể là bất kỳ chuỗi ký tự nào:

  • Nếu bạn có thể chắc chắn rằng chuỗi của bạn không sử dụng bit có ý nghĩa nhất trong mỗi byte, bạn có thể cắt từng chuỗi xuống còn bảy bit và sử dụng các thao tác bitwise để chuyển 56 bit còn lại thành 56 bit bạn có sẵn.

  • Nếu các chuỗi chỉ có các chữ cái và chữ số, hãy đưa ra biểu diễn 6 bit của tập hợp đó và tạo chuỗi 48 bit của mã định danh của bạn.

Nếu định dạng luôn là hai chữ cái theo sau là một chuỗi chữ số:

  • Để hai byte đầu tiên một mình và mã hóa số thành số nguyên sáu byte. IO123456trở thành 0x49 0x4f 0x01E240.

  • Để hai byte đầu tiên một mình và đóng gói các chữ số dưới dạng thập phân được mã hóa nhị phân . IO123456trở thành 0x49 0x4f 0x12 0x34 0x56.


1

Từ bối cảnh của câu hỏi được đăng ở đây, nó chỉ ra một số giao thức công nghiệp gọi là HART. Giao thức này có một cách duy nhất để bọc các ký tự ASCII. Nó được gọi là Gói-ASCII. Nhưng nó vẫn không đóng gói 8 ký tự thành 4! Theo Packed-ASCII, 8 byte ASCII được chuyển đổi thành 6. 4 thành 3 và cứ thế.

Trong giao thức này, độ dài của các tham số trong một yêu cầu nhất định luôn được cố định. Vì vậy, các nhân vật còn lại cần được đệm bởi các nhân vật Space. Tuy nhiên, tất cả những thứ này là HART-Cụ thể. Nếu bạn xác nhận rằng bạn đang làm việc này, tôi sẽ đưa ra quy trình đóng gói & giải nén chính xác.


0

Có thể bằng cách chuyển đổi '0123456' thành một số nguyên dài.

Nhưng điều này sẽ chỉ làm việc cho ID số.

Một kế hoạch khả thi khác là chuyển đổi mã hóa ECMA-1 7 đến 6 bit của bạn, nó sẽ cung cấp cho bạn một chuỗi Sáu byte nhưng bạn sẽ bị giới hạn ở bộ ký tự thành số chữ cái in hoa và một bộ ký tự dấu chấm câu giới hạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.