如何在Golang中检测非GSM字符?自动切换pdutext编码方案
自动选择GSM7/UCS2编码的高效实现
方案1:预编译正则表达式匹配(简洁易维护)
先预编译匹配GSM7字符集的正则,用它检测短信内容是否全为GSM7支持的字符:
import "regexp" // 预编译GSM7字符集正则,覆盖GSM 03.38标准所有支持的Unicode字符 var gsm7Regex = regexp.MustCompile(`^[\x00-\x1F\x20-\x7E\xA0\x8A\x8C\x8E\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F]*$`) // 检测字符串是否仅包含GSM7字符 func isGSM7(s string) bool { return gsm7Regex.MatchString(s) }
方案2:基于Map的字符查询(高性能场景首选)
预定义包含所有GSM7字符的映射表,遍历字符串时直接查询字符合法性,适合高并发、大量短信处理场景:
// 预定义GSM7支持的所有字符映射 var gsm7Chars = map[rune]bool{ // 基础GSM7字符(0x00-0x7E,排除转义符0x1B) '\x00': true, '\x01': true, '\x02': true, '\x03': true, '\x04': true, '\x05': true, '\x06': true, '\x07': true, '\x08': true, '\x09': true, '\x0A': true, '\x0B': true, '\x0C': true, '\x0D': true, '\x0E': true, '\x0F': true, '\x10': true, '\x11': true, '\x12': true, '\x13': true, '\x14': true, '\x15': true, '\x16': true, '\x17': true, '\x18': true, '\x19': true, '\x1A': true, '\x1C': true, '\x1D': true, '\x1E': true, '\x1F': true, '\x20': true, '\x21': true, '\x22': true, '\x23': true, '\x24': true, '\x25': true, '\x26': true, '\x27': true, '\x28': true, '\x29': true, '\x2A': true, '\x2B': true, '\x2C': true, '\x2D': true, '\x2E': true, '\x2F': true, '\x30': true, '\x31': true, '\x32': true, '\x33': true, '\x34': true, '\x35': true, '\x36': true, '\x37': true, '\x38': true, '\x39': true, '\x3A': true, '\x3B': true, '\x3C': true, '\x3D': true, '\x3E': true, '\x3F': true, '\x40': true, '\x41': true, '\x42': true, '\x43': true, '\x44': true, '\x45': true, '\x46': true, '\x47': true, '\x48': true, '\x49': true, '\x4A': true, '\x4B': true, '\x4C': true, '\x4D': true, '\x4E': true, '\x4F': true, '\x50': true, '\x51': true, '\x52': true, '\x53': true, '\x54': true, '\x55': true, '\x56': true, '\x57': true, '\x58': true, '\x59': true, '\x5A': true, '\x5B': true, '\x5C': true, '\x5D': true, '\x5E': true, '\x5F': true, '\x60': true, '\x61': true, '\x62': true, '\x63': true, '\x64': true, '\x65': true, '\x66': true, '\x67': true, '\x68': true, '\x69': true, '\x6A': true, '\x6B': true, '\x6C': true, '\x6D': true, '\x6E': true, '\x6F': true, '\x70': true, '\x71': true, '\x72': true, '\x73': true, '\x74': true, '\x75': true, '\x76': true, '\x77': true, '\x78': true, '\x79': true, '\x7A': true, '\x7B': true, '\x7C': true, '\x7D': true, '\x7E': true, // GSM7扩展/特殊字符 '\xA0': true, '\x8A': true, '\x8C': true, '\x8E': true, '\x91': true, '\x92': true, '\x93': true, '\x94': true, '\x95': true, '\x96': true, '\x97': true, '\x98': true, '\x99': true, '\x9A': true, '\x9B': true, '\x9C': true, '\x9D': true, '\x9E': true, '\x9F': true, } // 检测字符串是否仅包含GSM7字符 func isGSM7(s string) bool { for _, r := range s { if !gsm7Chars[r] { return false } } return true }
修改原有代码实现自动编码选择
无论用哪种方案,都可以通过isGSM7函数的结果动态选择编码:
smsContent := data_map[`sms`] var text pdutext.Codec if isGSM7(smsContent) { text = pdutext.GSM7(smsContent) } else { text = pdutext.UCS2(smsContent) } sm, err := smpp_transmitter.Submit(&smpp.ShortMessage{ Src: data_map[`sender_masking`], Dst: data_map[`msisdn`], Text: text, Register: pdufield.NoDeliveryReceipt, })
这两种实现都比逐个枚举字符更高效:正则方案代码简洁易维护,map方案查询速度接近O(1),仅需遍历一次字符串即可完成检测,适合生产环境使用。
内容的提问来源于stack exchange,提问作者Lezir Opav
相关产品推荐
相关产品推荐

