SNMP4J 处理中文信息时的问题
- 首先说,多数时候你并不会遇到SNMP中文问题
多数网络设备和网管软件都是西文的.这个"多数"的意思是95%以上.
目前有可能遇到的中文SNMP问题的场景:
1. 一些国产网络设备(别提华为,华为路由器的多数网管信息也是西文的)
2. Windows平台的SNMP服务
3. 一些国产网管软件
- SNMP4J处理中文时的问题:当遇到中文或者编码值大于 0x80 的字符时,就会直接以十六机制数输出
现象:
Vector<VariableBinding> responseVB = respEvent.getResponse().getVariableBindings(); if(1==responseVB.size()){ tempV = responseVB.elementAt(0); System.out.println(tempV.getOid().toString()+":"+tempV.getVariable()); System.out.println(tempV.getVariable().getSyntaxString()); } |
执行代码: 1.3.6.1.2.1.2.2.1.2.1:4d:53:20:54:43:50:20:4c:6f:6f:70:62:61:63:6b:20:69:6e:74:65:72:66:61:63:65:00 OCTET STRING 1.3.6.1.2.1.2.2.1.2.2:56:4d:77:61:72:65:20:56:69:72:74:75:61:6c:20:45:74:68:65:72:6e:65:74:20:41:64:61:70:74:65:72:20:66:6f:72:20:56:4d:6e:65:74:38:00 OCTET STRING 1.3.6.1.2.1.2.2.1.2.3:56:4d:77:61:72:65:20:56:69:72:74:75:61:6c:20:45:74:68:65:72:6e:65:74:20:41:64:61:70:74:65:72:20:66:6f:72:20:56:4d:6e:65:74:31:00 OCTET STRING 1.3.6.1.2.1.2.2.1.2.4:52:65:61:6c:74:65:6b:20:52:54:4c:38:31:33:39:20:46:61:6d:69:6c:79:20:50:43:49:20:46:61:73:74:20:45:74:68:65:72:6e:65:74:20:4e:49:43:20:2d:20:ca:fd:be:dd:b0:fc:bc:c6:bb:ae:b3:cc:d0:f2:ce:a2:d0:cd:b6:cb:bf:da:00 OCTET STRING 1.3.6.1.2.1.2.2.1.2.65542:41:53:55:53:20:38:30:32:2e:31:31:62:2f:67:20:57:69:72:65:6c:65:73:73:20:4c:41:4e:20:43:61:72:64:20:2d:20:ca:fd:be:dd:b0:fc:bc:c6:bb:ae:b3:cc:d0:f2:ce:a2:d0:cd:b6:cb:bf:da:00 OCTET STRING |
- 原因:问题出在SNMP4J的基础字符串类OctetString上。
(SNMP4J体系下的字符串是以OctetString的形式而不是String形式存在和处理的。各种和字符串有关的资源如community,version,user,password等都是基于OctetString)
问题出在OctetString类的toString方法:
public class OctetString extends AbstractVariable implements AssignableFromByteArray, AssignableFromString { public String toString() { if (isPrintable()) { return new String(value); } return toHexString(); // 没通过isPrintable()判断的,如ASCII控制字符,汉字等,都以16进制显示 } |
public boolean isPrintable() { for (int i=0; i<value.length; i++) { char c = (char)value[i]; if ((Character.isISOControl(c) || ((value[i] & 0xFF) >= 0x80)) && (!Character.isWhitespace(c))) { // 判断其是否大于0x80 (即通常所说的大于128的ASCII码,汉字编码都在这个区间内) return false; } } return true; } |
- 解决法1:网上有人给的建议是直接把OctetString类里toString方法里的if (isPrintable())部分取消掉,就是用基本的String转换
public String toString() { return new String(value); } |
测试:
1.3.6.1.2.1.2.2.1.2.1:MS TCP Loopback interface OCTET STRING 1.3.6.1.2.1.2.2.1.2.2:VMware Virtual Ethernet Adapter for VMnet8 OCTET STRING 1.3.6.1.2.1.2.2.1.2.3:VMware Virtual Ethernet Adapter for VMnet1 OCTET STRING 1.3.6.1.2.1.2.2.1.2.4:Realtek RTL8139 Family PCI Fast Ethernet NIC - 数据包计划程序微型端口 OCTET STRING 1.3.6.1.2.1.2.2.1.2.65542:ASUS 802.11b/g Wireless LAN Card - 数据包计划程序微型端口 OCTET STRING |
这种方法更不可取,因为isPrintable()方法是用于判断可显示字符的,其中 不止判断大于0x80,还有包括控制字符的判断(0-31,127-159)
(codePoint >= 0x0000 && codePoint <= 0x001F) || (codePoint >= 0x007F && codePoint <= 0x009F);
- 解决法2:克服法1的缺陷,toString()不变,只修改isPrintable()
public String toString() { if (isPrintable()) { return new String(value); } return toHexString(); } |
public boolean isPrintable() { for (int i=0; i<value.length; i++) { char c = (char)value[i]; int codePoint = (int)value[i]; if (((codePoint > 0x0000 && codePoint <= 0x001F) || (codePoint >= 0x007F && codePoint <= 0x009F)) && (!Character.isWhitespace(c))) { return false; } } return true; } |
注意: 上面codePoint变量的操作,基本就是Character.isISOControl(c)的操作
但windows 平台的snmp信息会以‘\0'结尾,这样windows平台任何snmp信息都通不过Character.isISOControl(c)的判断
所以必须把Character.isISOControl(c)中的codePoint > = 0x0000改成codePoint > 0x0000
- 解决法3:在国外的论坛上,有的比较死板的人要求按正规的“继承+覆写方法”的方式做修改,这样能保证源码的不被改变
其实仔细想想,完全不修改源码是很难的,所谓“牵一发而动全身”。
既然是开源的代码,该修改就修改.
解决法修改后,获取mac地址有问题,出现乱码。最好在出现中文的地方调用此方法:
public static String getChinese(String octetString) { //snmp4j遇到中文直接转成16进制字符串
try {
String[] temps = octetString.split(":");
byte[] bs = new byte[temps.length];
for (int i = 0; i < temps.length; i++)
bs[i] = (byte) Integer.parseInt(temps[i], 16);
return new String(bs, "GB2312");
} catch (Exception e) {
return null;
}
}
SNMP4J 处理中文信息时的问题相关推荐
- alert中文信息时乱码,html页面和script标签中均已设置为utf-8依然乱码
今天在原来的js文件中添加了一些新的逻辑判断,结果,alert的中文信息居然乱码,就是那种菱形的乱码,无语~ 网上的应对之策都是指定html文档和引入script标签时指定其编码,但公司是基于平台开发 ...
- 中文信息匮乏年代,新媒体粉墨登场
中文信息匮乏年代,新媒体粉墨登场 善于识别与把握时机是极为重要的.在一切大事业上,人在开始做事前要像千眼神那样察视时机,而在进行时要像千手神那样抓住时机. -- 培根,英国哲学家 三大门户网站正是识别 ...
- NCrawler爬取中文网页时乱码问题的解决方法
在使用.NET下的NCrawler爬取网页信息时,如果网页以GBK或GB2312进行编码,则下载的内容会出现乱码. 查找原因,发现在NCrawler.HtmlProcessor项目下HtmlDocum ...
- 基于Bert-NER构建特定领域中文信息抽取框架
向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程 公众号:datayx 知识图谱(Knowledge Graph)主要由实体.关系和属性构成,而信息抽取(Inform ...
- 【9月16日】中文信息MMT模型
近期读了<自然语言处理的形式模型>一书,为冯志伟老先生的科研精神点赞.致敬. 作者根据依存语法和德国配价语法的精髓,针对N.Chomsky短语结构语法的弱点和汉语语法的特点,在80年代初提 ...
- 自然语言处理核心期刊_中国中文信息学会
全国第十六届计算语言学会议(CCL 2017)及 第五届基于自然标注大数据的自然语言处理国际学术研讨会(NLP-NABD 2017)联合征稿启事 2017-03-20 "第十六届全国计算语言 ...
- python向json文件写入中文信息
''' 功能:python向json文件写入中文信息: 创建json数据. ''' import jsonorder_info={'订单需求信息': {'订单任务编号':'','观测目标名称':'', ...
- git提交中文信息报错
使用git一段时间了,还是会遇到一些问题,这里作一总结,后续有新问题了补充. 在提交信息中输入中文后出错 现象 add后commit,在vim中输入了中文提交信息,保存退出时出错,提示如下: 网上查了 ...
- 开启报名丨中文信息学会青工委学术沙龙:“推荐系统前沿进展”
在互联网大数据背景下,无论是信息消费者还是信息生产者都受到了信息过载问题的严重困扰.近年来,从海量数据中挖掘用户的偏好,并据此为用户提供个性化推荐日渐被工业界和学术界所重视,并逐渐成为各大互联网平台的 ...
最新文章
- 某小型公司持续集成工具 jenkins 实践
- Log4Net使用详解(续)
- python的jupyter的使用教程-JupyterNotebook设置Python环境的方法步骤
- windows系统-汇编语言与机器码的关系
- 计算机桌面堆,桌面堆 Desktop heap设置
- ServHa双机热备简单配置
- laravel 路由模型绑定
- 曾创下IRR62%的超高战绩的VC离开中国:一切因人而来因人而去
- IDEA设置注释模板
- qq聊天/msn聊天/发送邮件
- CSU - 1256 天朝的单行道
- 软考之网络工程师准备
- HDOJ 4622 Reincarnation (hash)
- Reactive 响应式编程简单使用
- 【前端监控系统】埋点数据上报的3种方式
- 深度学习的研究方向和发展趋势
- EPLAN创建3D宏部件
- PreTranslateMessage()函数的使用说明
- PMP考试流程是怎样的?
- android-pdf阅读器(Android开源项目)