อักขระ SMS นับระหว่างประเทศ

ฉันพบ นับอักขระ/sms โดยใช้ jQuery แต่ไม่รองรับอักขระสากล เช่น จีน ญี่ปุ่น ไทย ฯลฯ

var $remaining = $('#remaining'),
    $messages = $remaining.next();

$('#message').keyup(function(){
    var chars = this.value.length,
        messages = Math.ceil(chars / 160),
        remaining = messages * 160 - (chars % (messages * 160) || messages * 160);

    $remaining.text(remaining + ' characters remaining');
    $messages.text(messages + ' message(s)');
});

นี่คือตัวอย่างบางส่วนของการนับอักขระที่ไม่ถูกต้อง:

您好,請問คุณ吃飯了嗎? ‹‹ 11 ตัวอักษร

สวัสดีคุณกินหรือ? ‹‹ 17 ตัวอักษร

18 ตัวอักษร

안녕하자요, 당신이 먹는 거죠? ‹‹ 17 ตัวอักษร

हैलो, आप खाते हैं? ‹‹ 18 ตัวอักษร

Добры дзень, вы ясьце? ‹‹ 22 ตัวอักษร

ฉันจะทำให้งานนี้ใช้กับอักขระที่ไม่ใช่ ASCII ได้อย่างไร


person Ironman    schedule 28.03.2011    source แหล่งที่มา
comment
ดูเหมือนว่าจะนับได้ดีเป็นส่วนใหญ่ 您好,請問你吃飯了嗎? มีความยาว 11 อักขระ และตัวเลขสำหรับภาษาญี่ปุ่น เกาหลี และรัสเซียก็สามารถใช้ได้เช่นกัน คุณคาดหวังตัวเลขอะไร? อาจมีเฉพาะภาษาไทยและฮินดีเท่านั้น แต่ฉันไม่รู้ว่านับตัวอักษรอย่างไร   -  person deceze♦    schedule 28.03.2011
comment
ใช่ อย่างที่คุณบอกว่าภาษาไทยและฮินดีแตกต่างกัน ดีมีอักขระ 2 ตัวอยู่แล้ว ดังนั้น ตามที่ฉันพบ jquery ข้างต้น จะทำให้รองรับภาษาจีนนานาชาติ ไทย ญี่ปุ่น เกาหลี ฮินดี รัสเซียได้อย่างไร..   -  person Ironman    schedule 28.03.2011
comment
ใช่ แต่ 您 เป็น อักขระ UTF-8 หนึ่งตัว เห็นได้ชัดว่าคุณต้องการนับ ไบต์ ไม่ใช่อักขระใช่ไหม   -  person deceze♦    schedule 28.03.2011


คำตอบ (1)


ที่นี่คุณไม่สามารถนับ "ตัวละคร" ได้จริงๆ ตามบทความ SMS บน Wikipedia หนึ่งในการเข้ารหัสที่แตกต่างกันสามแบบใช้สำหรับ SMS (GSM 7 บิต, 8- บิต GSM และ UTF-16) ดังนั้นก่อนอื่น คุณจะต้องรู้/ตัดสินใจว่าจะใช้การเข้ารหัสใด

หากคุณรู้ว่าคุณจะใช้ UTF-16 อยู่เสมอ คุณสามารถนับจำนวน หน่วยโค้ด 16 บิต สตริงจะใช้เวลา SMS มาตรฐานสามารถประกอบด้วย 70 หน่วยรหัส 16 บิต แต่จะจำกัดข้อความที่เป็นอักขระละตินไว้ที่ 70 ตัวเช่นกัน ดังนั้น หากคุณต้องการใช้อักขระละตินแบบเต็ม 160 ตัว (พร้อมการเข้ารหัส 7 บิต) หรือ 140 ตัว (พร้อมการเข้ารหัส 8 บิต) คุณจะต้องแยกความแตกต่างระหว่างทั้งสามกรณี

ตัวอย่างการนับหน่วยโค้ด UTF-16 16 บิต:

var message = "您好,請問你吃飯了嗎?";

var utf16codeUnits = 0;

for (var i = 0, len = message.length; i < len; i++) {
  utf16codeUnits += message.charCodeAt(i) < 0x10000 ? 1 : 2;
}

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


แก้ไข

แม้จะได้รับการยอมรับแล้ว แต่ฉันก็แฮ็กฟังก์ชั่นที่ถูกต้องอย่างรวดเร็ว (เท่าที่ฉันสามารถพูดได้) คำนวณ GSM 7 บิต (ถ้าเป็นไปได้) และขนาด UTF-16 ของข้อความ SMS: http://jsfiddle.net/puKJb/

person RoToRa    schedule 28.03.2011
comment
แล้วการใช้ Math.ceil(Math.log(message.charCodeAt(i))/Math.log(2<<bits)) กับ bits จะเป็น 7 หรือ 8 แทนล่ะ? - person Gumbo; 28.03.2011
comment
@Gumbo: ฉันไม่คิดว่าจะใช้ที่นี่ การเข้ารหัส GSM 7 และ 8 บิตไม่ได้ขึ้นอยู่กับจุดโค้ด Unicode (ซึ่ง charCodeAt ส่งคืน) - person RoToRa; 28.03.2011
comment
ฉัน คิดว่า มาตรฐาน SMS ระบุ UCS-2 แทนที่จะเป็น UTF-16 ดังนั้นอักขระขนาด 2 ไบต์เท่านั้น และไม่มีอักขระนอก BMP - person Craig McQueen; 15.08.2011
comment
@RoToRa ในโค้ด jsfiddle gsm7bitUnits ใช้งานไม่ได้กับอักขระเน้นเสียงเช่น á ซึ่งพบได้ทั่วไปในภาษาสเปน - person kzfabi; 12.08.2013
comment
@RoToRa เพิ่งตรวจสอบเพิ่มเติมและพบว่าอักขระเช่น á ไม่ใช่ GSM ดังนั้นความยาวสูงสุดของข้อความ SMS ที่มีอักขระเหล่านั้นคือ 70 และอักขระเหล่านั้นจะถูกนับเป็น 1 หน่วย - person kzfabi; 12.08.2013