คุณบีบอัดสตริง ASCII เป็นไบต์ที่น้อยลงได้อย่างไร


12

ฉันทำงานกับอุปกรณ์ฝังตัวที่มีโปรโตคอลเฉพาะที่ส่งข้อความไปยังอุปกรณ์อื่นและฉันกำลังสร้างแอปพลิเคชันที่แยกวิเคราะห์แพ็คเก็ตที่ส่ง แต่ละแพ็คเก็ตมีขนาด 8 ไบต์ โพรโทคอลถูกกำหนดเป็นโดยที่ไบต์แรกเป็นส่วนหัวและ 7 ไบต์ที่เหลือคือข้อมูล

พวกเขาพยายามที่จะส่งสตริง ID เฉพาะ แต่สตริง ID ยาว 8 อักขระ (ASCII) ดังนั้นมันจะไม่พอดีกับ 7 ไบต์

สิ่งที่เพื่อนร่วมงานของฉันบอกฉันคือพวกเขากำลังจะเปลี่ยน 8 ไบต์ ASCII ของสตริงเดิมเป็นจำนวนเต็ม (ทศนิยม) และส่งให้ฉัน 4 ไบต์ พวกเขาบอกฉันว่าฉันควรจะได้รับสายดั้งเดิมจาก 4 ไบต์ ฉันมีปัญหาเวลาปิดหัวของฉันรอบนี้

ดังนั้นถ้าคุณมีสตริง ID เช่น "IO123456" นั่นคือ 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x35 0x36 ใน ASCII .. คุณจะบีบอัดมันใน 4 ไบต์ได้อย่างไรโดยเปลี่ยนเป็นจำนวนเต็มและฉันจะได้สตริงเดิมจากมัน ? ฉันทำอะไรหายหรือมีเพื่อนร่วมงานเข้าใจผิด? ฉันเข้าใจว่านี่เป็นคำถาม bizzare จริงๆ แต่สิ่งนี้ไม่ได้ทำให้ฉันรู้สึกอะไรเลย


1
อักขระ ASCII แต่ละตัวใช้เวลาเพียง 7 บิตดังนั้นสตริงที่มี 8 อักขระ ASCII สามารถถูกเก็บไว้ใน 8 * 7 บิต - 7 ไบต์
luiscubal

คำตอบ:


17

ID อยู่ในรูปแบบเสมอ: IO123456 หรือไม่ สิ่งที่เพื่อนร่วมงานของคุณอาจหมายถึงคือเขาส่งเฉพาะส่วนที่เป็นตัวเลขซึ่งเหมาะกับ 4 ไบต์โดยไม่ใส่ส่วน "IO"


1
นี่มัน สองไบต์แรกจะเป็นตัวอักษรเสมอและส่วนที่เหลือจะเป็นตัวเลขดังนั้นมันจึงสามารถใส่ได้อย่างง่ายดายใน 4 ไบต์ตามที่คุณพูด แม้ว่าฉันจะไม่รู้ว่ามาจากไหนจำนวน 4 ไบต์โดยพลการเพราะ 999999 ในฐานสิบหกคือ F423F ดังนั้นจึงเป็น 3 ไบต์มากที่สุด ..
l46kok

5
@ l46kok: จำนวนเต็ม 3 ไบต์ (24 บิต) หายากมากดังนั้นจึงอาจเป็นเรื่องง่ายสำหรับพวกเขาที่จะส่งเป็นจำนวนเต็ม 32- บิต (4 ไบต์) ฉันจะไม่แปลกใจเลยถ้าคุณได้มันมาในรูปแบบตัวแทน (ลำดับไบต์) ของอุปกรณ์ฝังตัว
Bart van Ingen Schenau

16

หากอักขระสองตัวแรกไม่คงที่ (แต่เป็นตัวอักษรเสมอ) และอักขระที่เหลืออีกหกตัวเป็นตัวเลขเสมอสตริงเช่น "IO123456" สามารถบรรจุลงใน 5 ไบต์โดยการแปลงตัวเลขให้เป็นรูปแบบเลขฐานสอง (BCD) แบบไบนารี :

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

หากมีตัวระบุที่เป็นไปได้จำนวน จำกัด (ตัวอักษรสองตัวแรก) คุณสามารถเข้ารหัสเหล่านี้เป็นตัวเลขและส่งแทน (ตราบใดที่ไม่มีชุดค่าผสมไม่เกิน 256 ชุด) เช่น:

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

ดังนั้นสตริงต้นฉบับจะถูกบรรจุใน 4 ไบต์โดยไม่มีการสูญหายของข้อมูล:

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

แน่นอนว่ากระบวนการนี้สามารถย้อนกลับเพื่อรับสตริง ID ดั้งเดิมได้


3

หากสตริงสามารถเป็นลำดับอักขระใด ๆ ได้:

  • หากคุณมั่นใจได้ว่าสายอักขระของคุณไม่ได้ใช้บิตที่มีความสำคัญมากที่สุดในแต่ละไบต์คุณสามารถสับได้หนึ่งถึงเจ็ดบิตและใช้การดำเนินการตามบิตเพื่อเปลี่ยน 56 บิตที่เหลือเป็น 56 บิตที่คุณมีอยู่

  • หากสตริงเป็นเพียงตัวอักษรและตัวเลขมาด้วยชุด 6 บิตของชุดนั้นและสร้างสตริงตัวระบุ 48 บิต

หากรูปแบบเป็นตัวอักษรสองตัวเสมอตามด้วยตัวเลข

  • ปล่อยสองไบต์แรกไว้คนเดียวและเข้ารหัสตัวเลขเป็นจำนวนเต็มหกไบต์ จะกลายเป็นIO1234560x49 0x4f 0x01E240

  • ปล่อยสองไบต์แรกไว้คนเดียวและแพ็คตัวเลขเป็นทศนิยมทศนิยมด้วย รหัสไบนารี จะกลายเป็นIO1234560x49 0x4f 0x12 0x34 0x56


1

จากบริบทของคำถามที่โพสต์ที่นี่มันชี้ไปที่บางโปรโตคอลอุตสาหกรรมที่เรียกว่า HART โปรโตคอลนี้มีวิธีที่ไม่ซ้ำกันในการห่ออักขระ ASCII มันถูกเรียกว่าเป็น Packed-ASCII แต่ก็ยังไม่แพ็ค 8 ตัวอักษรถึง 4! ตาม Packed-ASCII ไบต์ 8 ASCII จะถูกแปลงเป็น 6. 4 ถึง 3 และต่อไป

ในโปรโตคอลนี้ความยาวของพารามิเตอร์ในคำขอบางอย่างจะได้รับการแก้ไขเสมอ ดังนั้นตัวละครที่เหลือจะต้องถูกทับด้วยอักขระอวกาศ ถึงกระนั้นทุกสิ่งนี้เป็น HART-Specific หากคุณยืนยันว่าคุณกำลังทำสิ่งนี้อยู่ฉันจะทำตามขั้นตอนที่แน่นอนในการบรรจุและแกะกล่อง


0

อาจเป็นไปได้โดยการแปลง '0123456' เป็นจำนวนเต็มแบบยาว

แต่จะใช้งานได้กับรหัสตัวเลขเท่านั้น

อีกรูปแบบที่เป็นไปได้คือการแปลงการเข้ารหัส ECMA-1 7 ถึง 6 บิตซึ่งจะทำให้คุณมีสตริงหกไบต์ แต่คุณจะถูก จำกัด เฉพาะอักขระที่ตั้งค่าเป็นตัวเลขตัวอักษรตัวพิมพ์ใหญ่และอักขระเครื่องหมายวรรคตอนที่ จำกัด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.