【问题标题】:Python library for converting plain text (ASCII) into GSM 7-bit character set?用于将纯文本(ASCII)转换为 GSM 7 位字符集的 Python 库?
【发布时间】:2010-03-16 08:13:08
【问题描述】:

是否有用于将 ascii 数据编码为 7 位 GSM 字符集(用于发送 SMS)的 python 库?

【问题讨论】:

    标签: python encoding sms


    【解决方案1】:

    现在有:)

    感谢Chad 指出这不太正确

    Python2 版本

    # -*- coding: utf8 -*- 
    gsm = (u"@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>"
           u"?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà")
    ext = (u"````````````````````^```````````````````{}`````\\````````````[~]`"
           u"|````````````````````````````````````€``````````````````````````")
    
    def gsm_encode(plaintext):
        res = ""
        for c in plaintext:
            idx = gsm.find(c)
            if idx != -1:
                res += chr(idx)
                continue
            idx = ext.find(c)
            if idx != -1:
                res += chr(27) + chr(idx)
        return res.encode('hex')
    
    print gsm_encode(u"Hello World")
    

    输出为十六进制。显然,如果你想要二进制流,你可以跳过它

    Python3 版本

    # -*- coding: utf8 -*- 
    import binascii
    gsm = ("@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>?"
           "¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà")
    ext = ("````````````````````^```````````````````{}`````\\````````````[~]`"
           "|````````````````````````````````````€``````````````````````````")
    
    def gsm_encode(plaintext):
        res = ""
        for c in plaintext:
            idx = gsm.find(c);
            if idx != -1:
                res += chr(idx)
                continue
            idx = ext.find(c)
            if idx != -1:
                res += chr(27) + chr(idx)
        return binascii.b2a_hex(res.encode('utf-8'))
    
    print(gsm_encode("Hello World"))
    

    【讨论】:

    【解决方案2】:

    我从 gnibbler 的回答中得到了提示。这是我在查看在线转换器后以某种方式编写的脚本:http://smstools3.kekekasvi.com/topic.php?id=288,它对我来说可以正常工作。编码和解码。

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    gsm = (u"@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>"
       u"?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑÜ`¿abcdefghijklmnopqrstuvwxyzäöñüà")
    ext = (u"````````````````````^```````````````````{}`````\\````````````[~]`"
       u"|````````````````````````````````````€``````````````````````````")
    
    def get_encode(currentByte, index, bitRightCount, position, nextPosition, leftShiftCount, bytesLength, bytes):
        if index < 8:
            byte = currentByte >> bitRightCount
            if nextPosition < bytesLength:
                idx2 = bytes[nextPosition]
                byte = byte | ((idx2) << leftShiftCount)
                byte = byte & 0x000000FF
            else:
                byte = byte & 0x000000FF
            return chr(byte).encode('hex').upper()
        return ''
    
    def getBytes(plaintext):
        if type(plaintext) != str:
             plaintext = str(plaintext)
        bytes = []
        for c in plaintext.decode('utf-8'):
            idx = gsm.find(c)
            if idx != -1:
                bytes.append(idx)
            else:
                idx = ext.find(c)
                if idx != -1:
                    bytes.append(27)
                    bytes.append(idx)
        return bytes
    
    def gsm_encode(plaintext):
        res = ""
        f = -1
        t = 0
        bytes = getBytes(plaintext)
        bytesLength = len(bytes)
        for b in bytes:
            f = f+1
            t = (f%8)+1
            res += get_encode(b, t, t-1, f, f+1, 8-t, bytesLength, bytes)
    
        return res
    
    
    def chunks(l, n):
        if n < 1:
            n = 1
        return [l[i:i + n] for i in range(0, len(l), n)]
    
    def gsm_decode(codedtext):
        hexparts = chunks(codedtext, 2)
        number   = 0
        bitcount = 0
        output   = ''
        found_external = False
        for byte in hexparts:
        byte = int(byte, 16);
            # add data on to the end
            number = number + (byte << bitcount)
            # increase the counter
            bitcount = bitcount + 1
            # output the first 7 bits
            if number % 128 == 27:
                 '''skip'''
                 found_external = True
            else:
                if found_external == True:                
                     character = ext[number % 128]
                     found_external = False
                else:
                     character = gsm[number % 128]
                output = output + character
    
            # then throw them away
            number = number >> 7
            # every 7th letter you have an extra one in the buffer
            if bitcount == 7:
                if number % 128 == 27:
                    '''skip'''
                    found_external = True
                else:
                    if found_external == True:                
                        character = ext[number % 128]
                        found_external = False
                    else:
                        character = gsm[number % 128]
                    output = output + character
    
                bitcount = 0
                number = 0
        return output
    

    【讨论】:

      【解决方案3】:

      我找不到任何图书馆。但我认为这不应该需要图书馆。它有点容易做到。

      HereJon Skeet 本人在同一主题上。

      例子:

      s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      
      def ascii_to_gsm(ch):
          return bin(65 + s.index(ch))
      
      print ascii_to_gsm('A')
      print '--'
      
      binary_stream = ''.join([str(ascii_to_gsm(ch))[2:] for ch in s])
      print binary_stream
      

      您也可以使用dict 来存储mapping between ASCII and GSM 7-bit character set

      【讨论】:

        【解决方案4】:

        我最近遇到了一个类似的问题,我们从聚合器收到 gsm7bit 解码的短信,主要是针对带有西班牙字符的 Verizon 运营商,但我们无法成功解码。 这是我在论坛中其他答案的帮助下创建的。这适用于 Python 2.7.x。

        def gsm7bitdecode(text):
            gsm = (u"@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞ\x1bÆæßÉ !\"#¤%&'()*+,-./0123456789:;<=>"
                   u"?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑÜ`¿abcdefghijklmnopqrstuvwxyzäöñüà")
            ext = (u"````````````````````^```````````````````{}`````\\````````````[~]`"
                   u"|````````````````````````````````````€``````````````````````````")
        
            text = ''.join(["{0:08b}".format(int(text[i:i+2], 16)) for i in range(0, len(text), 2)][::-1])
        
            text = [(int(text[::-1][i:i+7][::-1], 2)) for i in range(0, len(text), 7)]
            text = text[:len(text)-1] if text[-1] == 0 else text
            text =iter(text)
        
            result = []
            for i in text:
                if i == 27:
                    i = next(text)
                    result.append(ext[i])
                else:
                    result.append(gsm[i])
        
            return "".join(result).rstrip()
        
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-11-10
          • 2017-06-03
          • 1970-01-01
          • 2012-05-22
          • 2010-10-06
          • 2014-04-29
          • 2012-07-19
          相关资源
          最近更新 更多