【发布时间】:2010-03-16 08:13:08
【问题描述】:
是否有用于将 ascii 数据编码为 7 位 GSM 字符集(用于发送 SMS)的 python 库?
【问题讨论】:
是否有用于将 ascii 数据编码为 7 位 GSM 字符集(用于发送 SMS)的 python 库?
【问题讨论】:
现在有:)
感谢Chad 指出这不太正确
# -*- 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")
输出为十六进制。显然,如果你想要二进制流,你可以跳过它
# -*- 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"))
【讨论】:
C#端口。
Ü 和¿ 之间的字符应该是§ (en.wikipedia.org/wiki/…)。
我从 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
【讨论】:
我找不到任何图书馆。但我认为这不应该需要图书馆。它有点容易做到。
Here 是 Jon 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。
【讨论】:
我最近遇到了一个类似的问题,我们从聚合器收到 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()
【讨论】: