در قسمت ۱۸+۱ از مجموعه آموزشی آردوینو با محوریت اینترنت اشیاء یاد گرفتیم که پیامها در استاندارد GSM (مانند پیامک و پاسخهای کدهای دستوری USSD) به صورت پیشفرض با رمزگذاری ASCII هفت بیتی رد و بدل میشوند. در صورتی که از حروف دیگری در پیامها استفاده شود، میبایستی به وسیله دستورات AT مربوطه، وضعیت کدپیج را روی حالت دیگری تنظیم کرد تا پیام به درستی منتقل شود.
مناسبترین کدپیج ماژولهای سیمکارت در حال حاضر برای حروف یونیکد، UCS-2 است. UCS-2 در واقع همان UTF-16 است که (مثل اوایل ایجاد UTF-16) به صورت ۲ بایتی ثابت، ۶۵,۵۳۶ حرف ابتدایی جدول یونیکد را پوشش میدهد.
ماژولهای سیمکارت پیامهای یونیکدی را به صورت Hex میگیرد و ارسال میکند؛ یعنی مثلا «0645» به جای «م» در جدول یونیکد.
در پروژهای نیاز بود تا میزان شارژ از طریق USSD گرفته شده و (از آنجایی که هر اپراتور متن تصادفی خودش را نشان میدهد 😄) متن پاسخ در صفحه وب به کاربر نمایش داده شود. تابع زیر که به زبان جاوا اسکریپت نوشته شده، ورودی Hex را به متن عادی تبدیل میکند:
1 2 3 4 5 6 7 8 9 10 |
function decodeUCS2String(str) { let decoded = "", strLen = str.length; if (strLen % 4 != 0) { throw new Error("Unexpected byte string length"); } for (let i = 0; i < strLen; i+=4) { decoded += String.fromCodePoint("0x"+str[i]+str[i+1]+str[i+2]+str[i+3]); } return decoded; } |
نکته مهم در این تبدیل این است که محتوای هگزی که ماژولهای سیمکارت بر میگردانند به صورت غیر Byte-Swap است (بایت سواپ یعنی بایتها جابجا هستند؛ یعنی اگر هر حرف ۲ بایت باشد، ابتدا بایت دومی و سپس بایت اولی قرار میگیرد). مثلا در تبدیل متن زیر:
064506270646062F0647002006270639062A0628062706310020062F06310020063306270639062A003A002006F006F9003A06F406F2000D000A06F106F006F006F006F006F00020063106CC062706440020000D000A06F1002D062E063106CC062F00200634062706310698000D000A000D000A06F906F9002D06280627063206AF0634062A
در صورتی که رمزگشایی به صورت Byte-swap باشد تبدیل خراب خواهد شد:
‘䔆✆䘆⼆䜆 ✆㤆⨆⠆✆ㄆ ⼆ㄆ ㌆✆㤆⨆㨀 句㨀ഀ ㄆ찆✆䐆 ഀⴀ⸆ㄆ찆⼆ 㐆✆ㄆ順ഀഀ句句ⴀ⠆✆㈆꼆㐆⨆’
در حالی که حالت غیر Byte-Swap به صورت صحیح رمزگشایی میشود:
مانده اعتبار در ساعت: ۰۹:۴۲
۱۰۰۰۰۰ ریال
۱-خرید شارژ
۹۹-بازگشت
یک ترفند: اگر نمیدانید ماژول سیمکارت پیام را به صورت ASCII میفرستد یا یونیکد، باقیمانده تقسیم تعداد حروف پیام بر ۴ را بگیرید؛ اگر ضریب ۴ بود احتمال قوی یونیکد است و اگر نبود ۱۰۰٪ یونیکد نیست!