这是一个可以检测并规范化文本中的URL地址的Java库。是由 Linkedin 公司 开源的一个URL探测工具:URL-Detector Java 库。
Linkedin 在每一秒钟,会检查数十万数量级的 URLs 。这些 URL 可能是来自恶意软件或者钓鱼网站的,为了保障每一个用户有一个安全的浏览体验,同时防止潜在的危险,Linkedin后端的内容检查服务程序会检查所有由用户产生的内容。为了在这每秒数十万规模的用户内容上检测不良的 URL,Linkedin要有能够在快速此规模上提取文本中URL 的方法。
Linkedin的服务器中的 URL地址有两种形式:
一种是单一的 URL
一种是在一大块的文本内容中
如果发送过来的是单一的 URL,Linkedin可以通过他们的内容检查服务直接验证;
如果发送过来的是大块的文本内容,Linkedin会先通过他们的URL探测器 ,经过搜索算法来验证这个文本是否有潜在危险的URL地址;
项目动机:
项目目标:检测出尽可能多的恶意链接,但是不希望仅仅局限于检测在 RFC 1738 中定义的URL地址,而是希望可以检测出任何能够在真正的浏览器地址栏中输入并且可以访问到的URL地址。因为,一个浏览器的地址栏中对 URL 的定义比起 在 RFC 1738 定义的来说,是非常松散的。同时,很多浏览器有不同的行为,所以,要找到一种URL文本规则能够被大部分流行的浏览器解析,它不是像RFC中定义语法那样简单。
最初,Linkedin开始第一种解决方案,基于正则表达式。它可以帮助检测到许多潜在的网址,其中有不少却是真的有潜在危险的,但是其中也有不少是没有的,而且有许多有危险的地址被遗漏了。用这种方式,为了抓取更多的地址这是一个反复匹配的过程,这可能出现一些不状况,比如,一个简单URL匹配的正则:
Regex: (ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?
然后,如果你想检测到不包含 scheme 的 URL,对应修改正则如下,这是其中一个的例子说明浏览器的地址栏可以解析的地址,但是却不符合 RFC 规范。
Regex: ((ftp|http|https):\/\/)?(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?
经过各种浏览器和多场景的兼容,终于得到最后的正则:
Regex: ((((f|ht)tps?:)?//)?([a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]+(:[^ @:]+)?@)?((([a-zA-Z0-9\\-]{1,255}|xn-- [a-zA-Z0-9\\-]+)\\.)+(xn--[a-zA-Z0-9\\-]+|[a-zA-Z]{2,6}|\\d{1,3})|localhost|(%[0-9a-fA-F]{2})+|[0-9]+) (:[0-9]{1,5})?([/\\?][^ \\s/]*)*)
正如你所看到的,每一个兼容或者一个新的场景带来的小的逻辑分支,就对应至少增加几个字符的正则表达式长度。你可以在 这里 看到这种情况究竟有多复杂(注意:一些类似的 URL 匹配的的正则表达式 长度竟然超过了5500字符)。许多通过这种方式检测到的 URL 虽然是科学的 ,但是却也带来了困扰。因为,越是频繁的变动正则,就会发现会有对应更多的误报 URL 。要是不优化这些正则,就发现遗漏的 URL 还很多。
因为发现了太多的错误的匹配,遂采取了减少匹配数量的方法。编辑原始的复杂的正则表达式语句使得引入了更多错误。因此,需要多正则表达式。下面的例子是其中一个正则表达式,用来排除“localhost”和“由数字和点组成的IPv4地址”。
Blacklisted Regex: ^((\\d+(\\.\\d+){0,2})|(\\d+(\\.\\d+){4,})|localhost)$
这样做的结果是,当解析大文本的时候,将耗费很长的时间,有些一次解析甚至是秒级别的。但是,Linkedin需要每秒处理数十万数量级的的 URL,这么耗时的这个方案明显是不可行的。同时,还发现正则表达式有一个缺点,就是:匹配易,处理分析难、维护难。就这样, URL探测器诞生了。
为了取代使用正则表达式,Linkedin 手工打造了一个有限状态机来解析出在文本中的URL。 有限状态机(你可以在这里了解更多信息)是由一组状态组成,状态之间可以由输入事件来触发状态转换。在这种请求下,输入事件就是在文本中正在解析的字符。
这个有限状态机有几个状态,主要是基于 URL 的各部分拆分的。状态由一系列的布尔变量保持,每一次一次消耗一个字符,同时进行一次状态转移。为了性能考虑,这个有限状态机器被设计成这样的逻辑拓扑顺序,没有箭头会从后面的状态指向前面的状态。举个例子,如果你在 host 后面检测到 “/”,那么状态机就不会再跟踪的 scheme ,因为它是点头过去的一端。如果状态机在任何一个位置撞到一个非预期的字符,它将返回上一次最新的结束状态,同时重新开始这个算法。
这个最棘手的部分是匹配字符。这些字符实际上,有可能在多个状态中存在。举个例子,比如冒号 “ : ”,它可以出现在至少三个地方:在 scheme 后面,在username 和 password 中间,或者是在 host 和 port 中间,并且,当我们处理IPv6的时候,它变的更加复杂,因为IPv6的地址也可以包括冒号的。但是,状态回溯主要是发生在一些奇怪的情况下,比如一个文本包含一系列非空白字符其中又包含多个冒号,而相比之下,正则表达式状态回溯会更加频繁。所以,我们的状态机的平均运行时间有显著的改善:
以下是一些关于性能提升的统计数据( 正则表达式 VS URL的探测器 ):
它是能够找到并检测任何网址,如:
HTML 5 Scheme – //www.linkedin
.com
用户名 -用户:pass@linkedi
n.com
电子邮件 - fred@linkedi
n.com
IPv4地址 – 192.168.1.1/hello.html
IPv4的八位字节 – 0×00.0×00.0×00.0x00IPv4的十进制 – HTTP:// 123 123 123 123 /
IPv6地址的 – FTP:// [:] /你好
IPv4映射的IPv6地址 – http://[fe30:4:3:0:192.3.2.1]/
另一个令人兴奋的是,它也能识别已经被识别过的URL的部分。例如,对于 URL:http://user@example.com:39000/hello?boo=ff#frag,它能识别到以下的部分:
Scheme – “http”
Username – “user”
Password – null
Host – “example.com”
Port – 39000
Path – “/hello”
Query – “?boo=ff”
Fragment – “#frag”
这个库还能够处理引号匹配和HTML。根据你输入的字符串,你可能想以某种特别的方式来处理某些字符。例如你正在解析一段 HTML,你可能想去除引号或者尖括号,比如,你输入的字符串像这样的:
<a href=”http://linke
想要使用这个库,只需要简单地从 GitHub 仓库上克隆下来,并导入 URL-Detector 库。下面是一个使用的示例:
import com.linkedin.urls.detection.UrlDetector; import com.linkedin.urls.detection.UrlDetectorOptions; ... UrlDetector parser = new UrlDetector("hello this is a url Linkedin.com", UrlDetectorOptions.Default); List<Url> found = parser.detect(); for(Url url : found) { System.out.println("Scheme: " + url.getScheme()); System.out.println("Host: " + url.getHost()); System.out.println("Path: " + url.getPath()); }
有关更详细的信息,可以到 Readme 里看 “如何使用”这一部分。
特别感谢 Vlad Shlosberg 和 Yulia Astakhova 对这个库的贡献。
如果大家有对这个库的改进建议,可以通过 GitHub 告诉我们;同时,如果有任何疑问,可以联系我们任何一个,我们将免费帮助你。祝你“探测”愉快!
via:码农网
maven引用 <dependency> <groupId>io.github.url-detector</groupId> <artifactId>url-detector</artifactId> <version>0.1.23</version> </dependency> public class TestController { private stat
我试图击中一个看起来像 。< br > < code > API shop . create([CreateCampaignService,{ auth _ token:user . token })] 我怎样才能使APIshop能够像这样的东西: 并点击 /
Cooja中的错误 我正在使用Contiki ng和示例udp服务器和udp客户端。我想做几件事:1-我希望客户端节点嗅探数据包,然后一旦嗅探到数据包,就向服务器发送数据包。我成功地做到了这一点,但有一些事情我不明白:a-当我在udp客户端中启动嗅探时,通过向代码中添加以下位: 这似乎只捕获udp客户端应用程序级别的数据包,当我增加QUEUEBUF\u CONF\u NUM以允许服务器接收这些数据
本文向大家介绍基于java URL和URLConnection(详解),包括了基于java URL和URLConnection(详解)的使用技巧和注意事项,需要的朋友参考一下 URL类将URL地址封装成对象,提供了解析URL地址的方法,如获取uri部分、host部分、端口等。 URLConnection则是URL对象和Socket连接给结合起来了,使得可以更轻松地获取发起URL请求的连接套接字。
我想在我的Spring mvc项目之一中实现基于URL的授权。在我的Spring mvc项目中,我使用java配置。我已将此站点https://www.baeldung.com/role-and-privilege-for-spring-security-registration以实现基于角色和特权的授权。 所以我创建了下面的表来实现。 这是用户表。 这个角色表。 这是角色和特权之间的映射表。 这
有谁能帮我..我想根据我的URL在我的菜单上添加一个活动类 这是密码 可能的URL 所以,我需要的是当URL是http://www.whatever.com/?tag=automotive,big-data时,我想再添加一个类,比如active。 示例: HTML:
7.2. 密码嗅探 尽管攻击者通过嗅探(察看)你的用户和应用间的网络通信并不专门用于访问控制,但要意识到数据暴露变得越来越重要,特别是对于验证信息。 使用SSL可以有效地防止HTTP请求和回应不被暴露。对任何使用https方案的资源的请求可以防止密码嗅探。最好的方法是一直使用SSL来发送验证信息,同时你可能还想用SSL来传送所有的包含会话标识的请求以防止会话劫持。 为防止用户验证信息不致暴露,在表