用python验证XMPP jid?
验证xmpp jid的正确方法是什么?语法已经描述过了,但我不太懂。而且,它看起来相当复杂,所以使用一个库来完成它似乎是一个好主意用python验证XMPP jid?,python,validation,xmpp,Python,Validation,Xmpp,验证xmpp jid的正确方法是什么?语法已经描述过了,但我不太懂。而且,它看起来相当复杂,所以使用一个库来完成它似乎是一个好主意 我目前正在使用xmpppy,但我似乎找不到如何用它来验证jid。感谢您的帮助 首先,当前JID的最佳参考是 我只是想在这里给你正则表达式,但有点失控,实现了所有规范: import re import sys import socket import encodings.idna import stringprep # These characters aren'
我目前正在使用xmpppy,但我似乎找不到如何用它来验证jid。感谢您的帮助 首先,当前JID的最佳参考是 我只是想在这里给你正则表达式,但有点失控,实现了所有规范:
import re
import sys
import socket
import encodings.idna
import stringprep
# These characters aren't allowed in domain names that are used
# in XMPP
BAD_DOMAIN_ASCII = "".join([chr(c) for c in range(0,0x2d) +
[0x2e, 0x2f] +
range(0x3a,0x41) +
range(0x5b,0x61) +
range(0x7b, 0x80)])
# check bi-directional character validity
def bidi(chars):
RandAL = map(stringprep.in_table_d1, chars)
for c in RandAL:
if c:
# There is a RandAL char in the string. Must perform further
# tests:
# 1) The characters in section 5.8 MUST be prohibited.
# This is table C.8, which was already checked
# 2) If a string contains any RandALCat character, the string
# MUST NOT contain any LCat character.
if filter(stringprep.in_table_d2, chars):
raise UnicodeError("Violation of BIDI requirement 2")
# 3) If a string contains any RandALCat character, a
# RandALCat character MUST be the first character of the
# string, and a RandALCat character MUST be the last
# character of the string.
if not RandAL[0] or not RandAL[-1]:
raise UnicodeError("Violation of BIDI requirement 3")
def nodeprep(u):
chars = list(unicode(u))
i = 0
while i < len(chars):
c = chars[i]
# map to nothing
if stringprep.in_table_b1(c):
del chars[i]
else:
# case fold
chars[i] = stringprep.map_table_b2(c)
i += 1
# NFKC
chars = stringprep.unicodedata.normalize("NFKC", "".join(chars))
for c in chars:
if (stringprep.in_table_c11(c) or
stringprep.in_table_c12(c) or
stringprep.in_table_c21(c) or
stringprep.in_table_c22(c) or
stringprep.in_table_c3(c) or
stringprep.in_table_c4(c) or
stringprep.in_table_c5(c) or
stringprep.in_table_c6(c) or
stringprep.in_table_c7(c) or
stringprep.in_table_c8(c) or
stringprep.in_table_c9(c) or
c in "\"&'/:<>@"):
raise UnicodeError("Invalid node character")
bidi(chars)
return chars
def resourceprep(res):
chars = list(unicode(res))
i = 0
while i < len(chars):
c = chars[i]
# map to nothing
if stringprep.in_table_b1(c):
del chars[i]
else:
i += 1
# NFKC
chars = stringprep.unicodedata.normalize("NFKC", "".join(chars))
for c in chars:
if (stringprep.in_table_c12(c) or
stringprep.in_table_c21(c) or
stringprep.in_table_c22(c) or
stringprep.in_table_c3(c) or
stringprep.in_table_c4(c) or
stringprep.in_table_c5(c) or
stringprep.in_table_c6(c) or
stringprep.in_table_c7(c) or
stringprep.in_table_c8(c) or
stringprep.in_table_c9(c)):
raise UnicodeError("Invalid node character")
bidi(chars)
return chars
def parse_jid(jid):
# first pass
m = re.match("^(?:([^\"&'/:<>@]{1,1023})@)?([^/@]{1,1023})(?:/(.{1,1023}))?$", jid)
if not m:
return False
(node, domain, resource) = m.groups()
try:
# ipv4 address?
socket.inet_pton(socket.AF_INET, domain)
except socket.error:
# ipv6 address?
try:
socket.inet_pton(socket.AF_INET6, domain)
except socket.error:
# domain name
dom = []
for label in domain.split("."):
try:
label = encodings.idna.nameprep(unicode(label))
encodings.idna.ToASCII(label)
except UnicodeError:
return False
# UseSTD3ASCIIRules is set, but Python's nameprep doesn't enforce it.
# a) Verify the absence of non-LDH ASCII code points; that is, the
for c in label:
if c in BAD_DOMAIN_ASCII:
return False
# Verify the absence of leading and trailing hyphen-minus
if label[0] == '-' or label[-1] == "-":
return False
dom.append(label)
domain = ".".join(dom)
try:
if node is not None:
node = nodeprep(node)
if resource is not None:
resource = resourceprep(resource)
except UnicodeError:
return False
return node, domain, resource
if __name__ == "__main__":
results = parse_jid(sys.argv[1])
if not results:
print "FAIL"
else:
print results
重新导入
导入系统
导入套接字
导入编码.idna
导入stringprep
#在使用的域名中不允许使用这些字符
#在XMPP中
BAD_DOMAIN_ASCII=”“.join([chr(c)表示范围(0,0x2d)内的c)+
[0x2e,0x2f]+
范围(0x3a、0x41)+
范围(0x5b、0x61)+
范围(0x7b,0x80)])
#检查双向字符有效性
def bidi(字符):
RandAL=map(stringprep.in_表_d1,字符)
对于RandAL中的c:
如果是c:
#字符串中有一个RandAL字符。必须进一步执行
#测试:
#1)必须禁止使用第5.8节中的字符。
#这是已经检查过的表C.8
#2)如果字符串包含任何RandALCat字符,则该字符串
#不能包含任何LCat字符。
如果过滤器(stringprep.in_表_d2,字符):
提出错误(“违反BIDI要求2”)
#3)如果字符串包含任何RandALCat字符,则
#RandALCat字符必须是
#字符串,并且RandALCat字符必须是最后一个
#字符串的字符。
如果不是RandAL[0]或不是RandAL[-1]:
提出错误(“违反BIDI要求3”)
def nodeprep(u):
字符=列表(unicode(u))
i=0
而我则是:
c=字符[i]
#化为乌有
如果stringprep.在表b1(c)中:
德尔查尔斯[i]
其他:
#箱折
chars[i]=stringprep.map\u table\u b2(c)
i+=1
#NFKC
chars=stringprep.unicodedata.normalize(“NFKC”,“join(chars))
对于以字符表示的c:
如果(表11(c)中的stringprep.或
表12(c)中的stringprep.或
表c21(c)中的stringprep.或
表c22(c)中的stringprep.或
表c3(c)中的stringprep.或
表c4(c)中的stringprep.或
表c5(c)中的stringprep.或
表c6(c)中的stringprep.或
表7(c)中的stringprep.或
表8(c)中的stringprep.或
表9(c)中的stringprep.或
在“\”和“/:@”中的c:
引发Unicode错误(“无效节点字符”)
比迪(查尔斯)
返回字符
def资源准备(res):
字符=列表(unicode(res))
i=0
而我则是:
c=字符[i]
#化为乌有
如果stringprep.在表b1(c)中:
德尔查尔斯[i]
其他:
i+=1
#NFKC
chars=stringprep.unicodedata.normalize(“NFKC”,“join(chars))
对于以字符表示的c:
如果(表12(c)中的stringprep.或
表c21(c)中的stringprep.或
表c22(c)中的stringprep.或
表c3(c)中的stringprep.或
表c4(c)中的stringprep.或
表c5(c)中的stringprep.或
表c6(c)中的stringprep.或
表7(c)中的stringprep.或
表8(c)中的stringprep.或
stringprep.in_表_c9(c)):
引发Unicode错误(“无效节点字符”)
比迪(查尔斯)
返回字符
def parse_jid(jid):
#第一关
m=重新匹配(“^(?([^\”&“/:@]{11023}”)?([^/@]{11023})(?:/({11023}))?$”,jid)
如果不是m:
返回错误
(节点、域、资源)=m.groups()
尝试:
#ipv4地址?
socket.inet\u pton(socket.AF\u inet,域)
除socket.error外:
#ipv6地址?
尝试:
socket.inet\u pton(socket.AF\u INET6,域)
除socket.error外:
#域名
dom=[]
对于域中的标签。拆分(“.”):
尝试:
label=encodings.idna.nameprep(unicode(标签))
编码.idna.ToASCII(标签)
除Unicode错误外:
返回错误
#UseSTD3ASCIIRules已设置,但Python的nameprep没有强制执行它。
#a)验证是否存在非LDH ASCII码点;就是
对于标签中的c:
如果c在坏的\u域\u ASCII中:
返回错误
#验证是否缺少前导和尾随连字符减号
如果标签[0]='-'或标签[-1]='-':
返回错误
dom.append(标签)
domain=“.”.join(dom)
尝试:
如果节点不是“无”:
node=nodeprep(节点)
如果资源不是无:
资源=资源准备(资源)
除Unicode错误外:
返回错误
返回节点、域、资源
如果名称=“\uuuuu main\uuuuuuuu”:
results=parse_jid(sys.argv[1])
如果没有结果:
打印“失败”
其他:
打印结果
是的,这是一个很大的工作。所有这些都有很好的理由,但如果工作组取得成果,我们希望将来能将其简化一些。很抱歉请求太晚;我本来打算按照您的方式实现它,但我想知道在代码点上的迭代是否真的适用于stringprep。在本文中,他们讨论的是字符,字符不一定等同于代码点(考虑组合变音符号)。还是我遗漏了一些关于unicode术语的内容?stringprep RFC是在IETF对unicode的观点做出细微的改变以解决问题之前编写的。当RFC说“字符”时,在大多数地方它的意思是“代码点”。我们正在努力