主动信息搜集

 

 

在内网中,好的信息搜集能力能够帮助开发者更快地拿到权限及达成目标。 内网里数据多种多样,需要根据需求寻找任何能对下一步渗透行动有所帮助的信 息。信息搜集能力是渗透过程中不可或缺的重要一步。下面将介绍各类搜集信息 的方法。

 

 

 

 

 

 

4.2.1    基于ICMP的主机发现

ICMP(Internet Control Message Protocol ,Internet报文协议)是TCP/IP的一种 子协议,位于OSI 7层网络模型中的网络层,其目的是用于在IP主机、路由器之间 传递控制消息。

1.ICMP工作流程

ICMP中提供了多种报文,这些报文又可分成两大类:“差错通知”和“信息查 询”。

(1)差错通知

当IP数据包在对方计算机处理过程中出现未知的发送错误时,ICMP会向发送 者传送错误事实以及错误原因等,如图4-1所示。

主动信息搜集_第1张图片

图4-1    差错通知

(2)信息查询

信息查询由一个请求和一个应答构成的。只需要向目标发送一个请求数据

包,如果收到了来自目标的回应,就可以判断目标是活跃主机,否则可以判断目 标是非活跃主机,如图4-2所示。

 

 

 

 

 

主动信息搜集_第2张图片

图4-2    信息查询

2.ICMP主机探测过程

Ping命令是ICMP中较为常见的一种应用,经常使用这个命令来测试本地与目 标之间的连通性,发送一个ICMP请求消息给目标主机,若源主机收到目标主机的 应答响应消息,则表示目标可达,主机存在。例如,我们所在的主机IP地址为

192.168.124.134 ,而通信的目标IP地址为192.168.124.5 。如果要判断192.168.124.5 是否为活跃主机,只需要向其发送一个ICMP请求,如果192.168.124.5这台主机处 于活跃状态,那么它在收到这个请求之后,就会给出一个回应,如下所示:

主动信息搜集_第3张图片

现在来编写一个利用ICMP实现探测活跃主机的代码程序。程序有很多种可实 现方式,此处我们借助Scapy库来完成。Scapy是Python中一个第三方库,在Scapy  库内部已经实现了大量的网络协议,例如TCP 、UDP 、IP 、ARP等,使用Scapy可 以灵活地编写各种网络工具。

首先我们对Scapy进行安装,命令如下:

 

 

 

 

 

 

 

安装过程如下所示:

主动信息搜集_第4张图片

接下来,我们可以利用Scapy库函数中的ICMP实现探测主机存活,详细过程 如下所示。

1)导入程序代码所应用到的模块:scapy 、random 、optparse ,其中scapy用  于发送ping请求和接收目标主机的应答数据,random用于产生随机字段,optparse 用于生成命行参数形式。示例如下:

#!/usr/bin/python

#coding:utf-8

from scapy .all import *

from random import randin t

from optparse import OptionParser

2)对用户输入的参数进行接收和批量处理,并将处理后的IP地址传入Scan函 数。

def main() :

parser = OptionParser("Usage:%prog -i  ")   # 输出帮助信息

parser .add_option( '-i ',type= 'string ',dest= 'IP ',help= 'specify target host ') # 获取IP地址参数

options,args = parser .parse_args()

print("Scan report for " + options .IP + "\n")

# 判断是单台主机还是多台主机

# IP中存在-,说明是要扫描多台主机

if '- ' in options .IP:

# 代码举例:192 .168 .1 .1-120

# 通过“ -”进行分隔,把192 .168 .1 .1和120分开

# 把192.168.1.1通过“,”进行分隔,取最后一个数作为range函数的start,然后把120+

1作为range函数的stop

# 这样循环遍历出需要扫描的IP地址

for i in range(in t(options .IP .split( '- ')[0] .split( ' . ')[3]), in t

(options .IP .split( '- ')[1]) + 1) :

Scan(

options .IP .split( ' . ')[0] + ' . ' + options .IP .split( ' . ')[1] + ' . ' + options .IP .split( ' . ')[2] + ' . ' + str(i))

time .sleep(0 .2)

 

 

 

 

 

else:

Scan(options .IP)

print("\nScan finished!. . .\n")

if __name__ == "__main__" :

try:

main()

except Keyboard Interrupt :

print("interrupted by user, killing all threads . . .")

 

3)Scan函数通过调用ICMP ,将构造好的请求包发送到目的地址,并根据目 的地址的应答数据判断目标主机是否存活。存活的IP地址会打印

出“xx.xx.xx.xx →Host is up” ,对于不存活的主机打印出“xx.xx.xx.xx →Host is down”:

icmp_id = randin t(1, 65535)

icmp_seq = randin t(1, 65535)

packet=IP(dst=ip,ttl=64,id=ip_id)/ICMP(id=icmp_id,seq=icmp_seq)/b '

rootkit '

result = sr1(packet, timeout=1, verbose=False)

if result :

for rcv in result :

scan_ip = rcv[IP] .src

print(scan_ip + '---> ' 'Host is up ')

else:

print(ip + '---> ' 'host is down ')

运行效果如下所示。

主动信息搜集_第5张图片

此处,我们也可以在程序中导入Nmap库函数,实现探测主机存活工具的编  写。这里使用Nmap函数的-sn与-PE参数,-PE表示使用ICMP ,-sn表示只测试该主 机的状态,具体步骤如下所示。

1)导入程序代码所应用到的模块:nmap 、optparse 。nmap模块用于产生 ICMP的请求数据包,optparse用于生成命令行参数。

#!/usr/bin/python3

# -*- coding: utf-8 -*

 

 

 

 

 

import nmap

import optparse

 

2)利用optparse模块生成命令行参数化形式,对用户输入的参数进行接收和 批量处理,最后将处理后的IP地址传入NmapScan函数。

if __name__ == '__main__ ' :

parser = optparse .OptionParser( 'usage: python %prog -i ip \n\n '

'Example: python %prog -i 192 .168 .1 .1 [192.168.1.1-100]\n')

# 添加目标IP参数-i

parser.add_option('-i','--ip',dest='targetIP',default='192.168.1.1 ',type='string', help= 'target ip address ')

options,args = parser .parse_args()

# 判断是单台主机还是多台主机

# IP中存在“ -”,说明是要扫描多台主机

if '- ' in options .target IP:

# 代码举例:192 .168 .1 .1-120

# 通过 '- '进行分割,把192 .168 .1 .1和120进行分离

# 把192.168.1.1通过“,”进行分隔,取最后一个数作为range函数的start,然后把 120+1作为range函数的stop

# 这样循环遍历出需要扫描的IP地址

for i in range(in t(options .target IP .split( '- ')[0] .split( ' . ')[2]),in t (options .target IP .split( '- ')[1])+1) :

NmapScan(options .target IP .split( ' . ')[0] + ' . ' + options .target IP . split( ' . ')[1] + ' . ' + options .target IP .split( ' . ')[2] + ' . ' +  str(i))

else:

NmapScan(options .target IP)

3)NmapScan函数通过调用nm.scan() 函数,传入-sn-PE参数,发起ping扫 描,并打印出扫描后的结果。

def NmapScan(target IP) :

# 实例化PortScanner对象

nm = nmap .PortScanner()

try:

# hosts为目标IP地址,argusments为Nmap的扫描参数

# -sn:使用ping进行扫描

# -PE:使用ICMP的 echo请求包(-PP:使用timestamp请求包 -PM:netmask请求包) result = nm .scan(hosts=target IP, arguments= '-sn -PE ')

# 对结果进行切片,提取主机状态信息

state = result[ 'scan '][target IP][ 'status '][ 'state ']

print("[{}] is [{}]" .format(target IP, state))

except Exception  as e:

pass

运行效果如下所示。

1195a21a25f94abfaff0d8edb9245074.png

基于ICMP的探测主机存活是一种很常见的方法,无论是以太网还是互联网都

 

 

 

 

 

可以使用这种方法。但是该方法也存在一定的缺陷,就是当网络设备,例如路由 器、防火墙等对ICMP采取了屏蔽策略时,就会导致扫描结果不准确。

 

 

 

 

 

4.2.2    基于TCP 、UDP的主机发现

 

基于TCP 、UDP的主机发现属于四层主机发现,是一个位于传输层的协议。 可以用来探测远程主机存活、端口开放、服务类型以及系统类型等信息,相比于 三层主机发现更为可靠,用途更广。

TCP是一种面向连接的、可靠的传输通信协议,位于IP层之上,应用层之下 的中间层。每一次建立连接都基于三次握手通信,终止一个连接也需要经过四次 握手,建立完连接之后,才可以传输数据。当主动方发出SYN连接请求后,等待 对方回答TCP的三次握手SYN+ACK ,并最终对对方的SYN执行ACK确认。这种 建立连接的方法可以防止产生错误的连接,所以TCP是一个可靠的传输协议。

因此,我们可以利用TCP三次握手原理进行主机存活的探测。当向目标主机 直接发送ACK数据包时,如果目标主机存活,就会返回一个RST数据包以终止这 个不正常的TCP连接。也可以发送正常的SYN数据包,如果目标主机返回

SYN/ACK或者RST数据包,也可以证明目标主机为存活状态。其工作原理主要依 据目标主机响应数据包中flags字段,如果flags字段有值,则表示主机存活,该字 段通常包括SYN 、FIN 、ACK 、PSH 、RST 、URG六种类型。SYN表示建立连

接,FIN表示关闭连接,ACK表示应答,PSH表示包含DATA数据传输,RST表示 连接重置,URG表示紧急指针。

现在来编写一个利用TCP实现的活跃主机扫描程序,这个程序有很多种方式 可以实现,首先借助Scapy库来完成。在安装好Scapy的终端输入Scapy运行程序。 设定远程IP地址为39.xx.xx.238 ,flag标志为A表示给目标主机发送ACK应答数据  包,通过sr1() 函数将构造好的数据包发出。相关代码如下所示:

>>> ip=IP()

>>> tcp=TCP()

>>> r=(ip/tcp)

>>> r[IP] .dst="39 .xx .xx .238"

>>> r[TCP] .flags="A"

>>> a=sr1(r)

>>> a .display()

通过a.display() 函数查看目标主机的返回数据包信息,此时可以发现flags   标志位为R ,表示远程主机给源主机发送了一个REST 。由此可以验证远程目标主 机为存活状态。响应结果如下所示。

 

 

 

 

 

1)导入程序代码所应用到的模块:time 、optparse 、random和scapy 。time模  块主要用于产生延迟时间,optparse用于生成命行参数,random模块用于生成随机 的端口,scapy用于以TCP发送请求以及接收应答数据,例如:

 

import time

from optparse import OptionParser

from random import randin t

from scapy .all import *

2)利用optparse模块生成命令行参数化形式,对用户输入的参数进行接收和 批量处理,最后将处理后的IP地址传入Scan() 函数。

def main() :

usage = "Usage: %prog -i "     # 输出帮助信息

parse = OptionParser(usage=usage)

parse .add_option("-i", '--ip ', type="string", dest="target IP", help=

"specify the IP address")          # 获取网段地址

options, args = parse .parse_args()          #实例化用户输入的参数

if '- ' in options .target IP:

# 代码举例:192 .168 .1 .1-120

# 通过“ -”进行分隔,把192 .168 .1 .1和120进行分离

# 把192.168.1.1通过“,”进行分隔,取最后一个数作为range函数的start,然后把 120+1作为range函数的stop

# 这样循环遍历出需要扫描的IP地址

 

 

 

 

 

for i in range(in t(options .target IP .split( '- ')[0] .split( ' . ')[3]), in t (options .target IP .split( '- ')[1]) + 1) :

Scan(options .target IP .split( ' . ')[0] + ' . ' + options .target IP .split  ( ' . ')[1] + ' . ' + options .target IP .split( ' . ')[2] + ' . ' + str(i))

else:

Scan(options .target IP)

if __name__ == '__main__ ' :

main()

 

3)Scan() 函数,通过调用TCP将构造好的请求包发送到目的地址,并根据 目的地址的响应数据包中flags字段值判断主机是否存活。若flags字段为R ,其整

型数值为4时表示接收到了目标主机的REST , 目标主机为存活状态,打印 出“xx.xx.xx.xx Host is up” ,否则为不存活主机,打印出“xx.xx.xx.xx Host is down”。

def Scan(ip) :

try:

dport = random .randin t(1, 65535)          #随机目的端口

packet = IP(dst=ip)/TCP(flags="A",dport=dport)     #构造标志位为ACK的数据包

response = sr1(packet,timeout=1 .0, verbose=0)

if response:

if in t(response[TCP] .flags) == 4:     #判断响应包中是否存在RST标志位

time .sleep(0 .5)

print(ip + ' ' + "is up")

else:

print(ip + ' ' + "is down")

else:

print(ip + ' ' + "is down")

except :

pass

运行效果如下所示。

主动信息搜集_第6张图片

同时,可以打开Wireshark软件进行流量监听,根据抓到的数据流量可以分 析,源主机向目标主机发送ACK请求,当主机存活时, 目标主机会发送一个

REST的应答数据包,效果如图4-3所示。

 

主动信息搜集_第7张图片

 

 

 

图4-3    向目标主机发送ACK请求时的监听效果

UDP(User Datagram Protocol ,用户数据报协议)是一种利用IP提供面向无  连接的网络通信服务。UDP会把应用程序发来的数据,在收到的一刻立即原样发 送到网络上。即使在网络传输过程中出现丢包、顺序错乱等情况时,UDP也不会 负责重新发送以及纠错。当向目标发送一个UDP数据包之后, 目标是不会发回任 何UDP数据包的。不过,如果目标主机处于活跃状态,但是目标端口是关闭状态 时,会返回一个ICMP数据包,这个数据包的含义为unreachable 。如果目标主机不 处于活跃状态,这时是收不到任何响应数据的。利用UDP原理可以实现探测存活 主机。

现在来编写一个利用UDP实现的活跃主机的扫描程序,首先借助Scapy库来完 成。在安装好Scapy的终端输入Scapy运行程序。设定远程IP地址为39.xx.xx.238,

端口dport可为任意值,此处将dport设为7345 ,通过sr1() 函数将构造好的数据包 发出。相关代码如下所示:

>>> udp=UDP()

>>> r = (ip/udp)

>>> r[IP] .dst="192 .168 .19 .141"

>>> r[UDP] .dport=734

>>> a=sr1(r)

如果目标主机处于存活状态,则会接收到目标主机的应答信息,可通过

a.display() 函数查看数据包信息。可以查看到返回的信息中存在ICMP的应答信 息,“code=port-unreachable”表示目标端口不可达。由此可以验证远程目标主机为 存活状态。若目标主机不为存活状态,则不会收到目标主机的响应数据包。响应 结果如下所示。

 

 

 

 

 

根据以上UDP发现存活主机的原理,我们可以编写相应的Python工具进行实 现,具体过程如下所示:

1)导入程序代码所应用到的模块:time 、optparse 、random和scapy 。time模  块主要用于产生延迟时间,optparse模块用于生成命令行参数,random模块用于生 成随机的端口,scapy模块用于以UDP发送请求以及接收应答数据。

 

#!/usr/bin/python

import time

from optparse import OptionParser

from random import randin t

from scapy .all import *

2)利用optparse模块生成命令行参数化形式,对用户输入的参数进行接收和 批量处理,最后将处理后的IP地址传入Scan() 函数。

def main() :

usage = "Usage: %prog -i "     # 输出帮助信息

parse = OptionParser(usage=usage)

parse .add_option("-i", '--ip ', type="string", dest="target IP", help=

"specify the IP address")          # 获取网段地址

options, args = parse .parse_args()          #实例化用户输入的参数

if '- ' in options .target IP:

# 代码举例:192 .168 .1 .1-120

# 通过“ -”进行分隔,把192 .168 .1 .1和120进行分离

# 把192.168.1.1通过“,”进行分隔,取最后一个数作为range函数的start,然后把 120+1作为range函数的stop

# 这样循环遍历出需要扫描的IP地址

for i in range(in t(options .target IP .split( '- ')[0] .split( ' . ')[3]), in t (options .target IP .split( '- ')[1]) + 1) :

Scan(options .target IP .split( ' . ')[0] + ' . ' + options .target IP .split  ( ' . ')[1] + ' . ' + options .target IP .split( ' . ')[2] + ' . ' + str(i))

 

 

 

 

 

else:

Scan(options .target IP)

 

if __name__ == '__main__ ' :

main()

 

3)Scan() 函数,通过调用UDP将构造好的请求包发送到目的地址,并根据 是否接收到目标主机的响应数据包判断主机的存活状态。若接收到响应数据包,

proto字段整型数据为1时,则代表目标主机为存活状态,打印出“xx.xx.xx.xx Host is up” ,否则为不存活主机,打印出“xx.xx.xx.xx Host is down”。

def Scan(ip) :

try:

dport = random .randin t(1, 65535)

packet = IP(dst=ip)/UDP(dport=dport)

response = sr1(packet,timeout=1 .0, verbose=0)

response:

if in t(response[IP] .proto) == 1:

time .sleep(0 .5)

print(ip + ' ' + "is up")

else:

print(ip + ' ' + "is down")

else:

print(ip + ' ' + "is down")

except :

pass

运行效果如下所示。

主动信息搜集_第8张图片

同时,可以打开Wireshark软件进行流量监听,根据抓到的数据流量可以分 析,源主机向目标主机发送UDP数据包,当主机存活时, 目标主机会发送一

个“Destination unreachableb(port unreachable )” 的应答数据包,效果如图4-4所 示。

 

 

 

 

 

主动信息搜集_第9张图片

图4-4    向目标主机发送UDP数据包时的监听效果

对于TCP 、UDP主机发现,同样可以借助Nmap库来实现。这里需要用到

Nmap的-sT和-PU两个参数。详细的代码过程这里不再赘述,读者可在4.2.1节的基 础上进行修改,所需修改代码部分如下所示:

 

result = nm .scan(hosts=target IP, arguments= '-sT ')

TCP主机发现的测试命令及效果如下:

2a083cbe87a448ceb7e07bfc8341fd4f.png

result = nm .scan(hosts=target IP, arguments= '-PU ')

UDP主机发现的测试效果如下:

21332f3874664a1191e1935ab9181a20.png

 

 

 

 

 

 

4.2.3    基于ARP的主机发现

 

ARP协议(地址解析协议)属于数据链路层的协议,主要负责根据网络层地 址(IP)来获取数据链路层地址(MAC)。

以太网协议规定,同一局域网中的一台主机要和另一台主机进行直接通信, 必须知道目标主机的MAC地址。而在TCP/IP中,网络层只关注目标主机的IP地  址。这就导致在以太网中使用IP协议时,数据链路层的以太网协议接收到的网络 层IP协议提供的数据中,只包含目的主机的IP地址。于是需要ARP协议来完成IP  地址到MAC地址的转换。假设我们当前的以太网结构如图4-5所示。

主动信息搜集_第10张图片

图4-5    以太网结构

在上述以太网结构中,假设PC1想与PC3通信,步骤如下。

1)PC1知道PC3的IP地址为192.168.1.3,然后PC1会检查自己的APR缓存表中 该IP是否有对应的MAC地址。

2)如果有,则进行通信。如果没有,PC1就会使用以太网广播包来给网络上 的每一台主机发送ARP请求,询问192.168.1.3的MAC地址。ARP请求中同时也包 含了PC1的IP地址和MAC地址。以太网内的所有主机都会接收到ARP请求,并检 查是否与自己的IP地址匹配。如果不匹配,则丢弃该ARP请求。

3)PC3确定ARP请求中的IP地址与自己的IP地址匹配,则将ARP请求中PC1 的IP地址和MAC地址添加到本地ARP缓存中。

 

 

 

 

4)PC3将自己的MAC地址发送给PC1。

5)PC1收到PC3的ARP响应时,将PC3的IP地址和MAC地址都更新到本地 ARP缓存表中。

本地ARP缓存表是有生存周期的,生存周期结束后,将再次重复上面的过 程。

当目标主机与我们处于同一以太网的时候,利用ARP进行主机发现是一个最  好的选择。因为这种扫描方式快且精准。现在我们借助Scapy来编写ARP主机发现 脚本,通过脚本对以太网内的每个主机都进行ARP请求。若主机存活,则会响应  我们的ARP请求,否则不会响应。因为ARP涉及网络层和数据链路层,所以需要  使用Scapy中的Ether和ARP 。Scapy中的ARP参数如下所示:

主动信息搜集_第11张图片

Scapy中的Ether参数如下所示:

8d9919dcdd444945a7ae2f1b02cf4bf2.png

这里介绍一下脚本中所使用的参数。Ether中src表示源MAC地址,dst表示目 的MAC地址。ARP中op代表消息类型,1为ARP请求,2为ARP响应,hwsrc和psrc 表示源MAC地址和源IP地址,pdst表示目的IP地址。接下来我们编写ARP主机发  现脚本。

1)写入脚本信息,导入相关模块:

U

#!/usr/bin/python3

# -*- coding: utf-8 -*-

import

import

import

from scapy .all import *

 

 

 

 

 

2)编写本机IP地址和MAC地址获取函数,通过正则表达式来进行获取:

 

# 取IP地址和MAC地址函数

def HostAddress(iface) :

# os .popen执行后返回执行结果

ipData = os .popen( 'ifconfig '+iface)

# 对ipData进行类型转换,再用正则进行匹配

dataLine = ipData .readlines()

# re .search利用正则匹配返回第一个成功匹配的结果,存在结果则为true

# 取MAC地址

if re .search( '\w\w:\w\w:\w\w:\w\w:\w\w:\w\w ',str(dataLine)) :

# 取出匹配的结果

MAC = re .search( '\w\w:\w\w:\w\w:\w\w:\w\w:\w\w ',str(dataLine)) .group(0) # 取IP地址

if re .search(r '((2[0-4]\d|25[0-5]|[01]?\d\d?)\ .){3}(2[0-4]\d|25[0-5]|[01]?

\d\d?) ',str(dataLine

)) :

IP = re .search(r '((2[0-4]\d|25[0-5]|[01]?\d\d?)\ .){3}(2[0-4]\d|25[0-5]| [01]?\d\d?) ',str(dataLine)) .group(0)

# 将IP和MAC通过元组的形式返回

addressInfo = (IP,MAC)

return addressInfo

3)编写ARP探测函数,根据本机的IP地址和MAC地址信息, 自动生成目标 进行探测并把结果写入文件:

# ARP扫描函数

def ArpScan(iface= 'eth0 ') :

# 通过HostAddres返回的元组取出MAC地址

mac = HostAddress(iface)[1]

# 取出本机IP地址

ip = HostAddress(iface)[0]

# 对本机IP地址进行分隔并作为依据元素,用于生成需要扫描的IP地址

ipSplit = ip .split( ' . ')

# 需要扫描的IP地址列表

ipList = []

# 根据本机IP生成IP扫描范围

for i in range(1,255) :

ipItem = ipSplit[0] + ' . ' + ipSplit[1] + ' . ' + ipSplit[2] + ' . ' + str(i) ipList.append(ipItem)

'''

发送ARP包

因为要用到OSI的二层和三层,所以要写成Ether/ARP。

因为最底层用到了二层,所以要用srp()发包

'''

result=srp(Ether(src=mac,dst= 'FF:FF:FF:FF:FF:FF ')/ARP(op=1,hwsrc=mac,hwdst= '00:00:00:00:00:00 ',pds t=ipList),iface=iface,timeout=2,verbose=False)

# 读取result中的应答包和应答包内容

resultAns = result[0] .res

# 存活主机列表

liveHost = []

# number 为接收到应答包的总数

number = len(resultAns)

print("=====================")

print("ARP 探测结果")

print("本机IP地址 :"  + ip)

print("本机MAC地址 :" + mac)

print("=====================")

for x in range(number) :

IP = resultAns[x][1][1] .fields[ 'psrc ']

MAC = resultAns[x][1][1] .fields[ 'hwsrc ']

liveHost.append([IP,MAC])

print("IP:" + IP + "\n\n" + "MAC:" + MAC  )

print("=====================")

# 把存活主机IP写入文件

 

 

 

 

 

resultFile = open("result","w")

for i in range(len(liveHost)) :

resultFile .write(liveHost[i][0] + "\n")

resultFile .close()

 

4)编写main 函数,利用optparse模块生成命令行参数化形式:

if __name__ == '__main__ ' :

parser = optparse .OptionParser( 'usage: python %prog -i interfaces \n\n ' 'Example: python %prog -i e th0\n ')

# 添加网卡参数 -i

parser .add_option( '-i ', '--iface ',dest= 'iface ',default= 'eth0 ',type= 'string ', help= 'interfaces name ')

(options, args) = parser .parse_args()

ArpScan(options .iface)

这样我们的ARP主机发现脚本功能就完成了。脚本测试结果下所示:

主动信息搜集_第12张图片

主动信息搜集_第13张图片

查看结果文件如下所示:

 

 

639562086b7c48d7a6ebceb2d39bb4ae.png

 

提示:普通用户运行时需要进行sudo ,否则会出现Operation not permitted提 醒!

下面介绍通过Nmap库来实现ARP主机发现,这里需要用到Nmap的-PR参数。 详细的过程此处不再赘述,读者可在4.2.1节的基础上进行修改,所需修改的代码 部分如下所示:

U

result = nm .scan(hosts=target IP, arguments= '-PR ')

ARP主机发现,测试效果如下所示:

1e89823d7f13453eb1b47018bbf61468.png

 

 

 

 

 

 

4.2.4    端口探测

 

端口是设备与外界通信交流的接口。如果把服务器看作一栋房子,那么端口 就是可以进出这栋房子的门。真正的房子只有一个或几个门,但是服务器可以至 多有65 536个门。不同的端口(门)可以指向不同的服务(房间)。

例如,我们经常浏览网页时涉及的WWW服务用的是80号端口,上传或下载 文件时的FTP服务用的是21号端口,远程桌面用的是3389号端口。

所以入侵者想要获取到房子(服务器)的控制权,势必要先从一个门进入一 个房间,再通过这个房间控制整个房子。那么服务器开了几个端口,端口后面的 服务是什么,这些都是十分重要的信息,可以为入侵者制定详细的入侵计划提供 依据。因此在信息搜集阶段,端口开放情况的扫描就显得尤为重要。

下面将通过Python的Socket模块来编写一个简便的多线程端口扫描工具。

1)导入脚本信息以及相关的模块:

 

#!/usr/bin/python3

# -*- coding:utf-8 -*-

import import import import import

sys

socket

optparse

threading

queue

2)编写一个端口扫描类,继承threading.Thread 。这个类需要传递3个参数, 分别是目标IP 、端口队列、超时时间。通过这个类创建多个子线程来加快扫描进 度:

# 端口扫描类,继承threading .Thread

class PortScaner(threading .Thread) :

# 需要传入端口队列、 目标IP,探测超时时间

def __init__(self, portqueue, ip, timeout=3) :

threading .Thread.__init__(self)

self._portqueue = portqueue

self._ip = ip

self._timeout = timeout

def run(self) :

while True:

# 判断端口队列是否为空

if self._portqueue .empty() :

# 端口队列为空,说明已经扫描完毕,跳出循环

break

# 从端口队列中取出端口,超时时间为1s

port = self._portqueue .get(timeout=0 .5)

try:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s .settimeout(self._timeout)

 

 

 

 

 

result_code = s .connect_ex((self._ip, port))

# sys .stdout.write("[%d]Scan\n" % port)

# 若端口开放,则会返回0

if result_code == 0:

sys .stdout.write("[%d] OPEN\n" % port)

except Exception as e:

print(e)

finally:

s .close()

 

3)编写一个函数,根据用户的参数来指定目标IP 、端口队列的生成以及子线 程的生成,同时能支持单个端口的扫描和范围端口的扫描:

def StartScan(targetip, port, threadNum) :

# 端口列表

port List = []

portNumb = port

# 判断是单个端口还是范围端口

if '- ' in port :

for i in range(in t(port.split( '- ')[0]), in t(port.split( '- ')[1])+1) : port List.append(i)

else:

port List.append(in t(port))

# 目标IP地址

ip = targetip

# 线程列表

threads = []

# 线程数量

threadNumber = threadNum

# 端口队列

portQueue = queue .Queue()

# 生成端口,加入端口队列

for port in port List :

portQueue .put(port)

for t in range(threadNumber) :

threads .append(PortScaner(portQueue, ip, timeout=3))

# 启动线程

for thread in threads:

thread.start()

# 阻塞线程

for thread in threads:

thread.join()

4)编写主函数来制定参数的规则:

if __name__ == '__main__ ' :

parser = optparse .OptionParser( 'Example: python %prog -i 127 .0 .0 .1 -p

80 \n      python %prog -i 127 .0 .0 .1 -p 1-100\n ')

# 目标IP参数-i

parser .add_option( '-i ', '--ip ', dest= 'target IP ',default= '127 .0 .0 .1 ', type= 'string ',help= 'target IP ')

# 添加端口参数-p

parser .add_option( '-p ', '--port ', dest= 'port ', default= '80 ', type= 'string ', help= 'scann port ')

# 线程数量参数-t

parser .add_option( '-t ', '--thread ', dest= 'threadNum ', default=100, type= 'in t ', help= 'scann thread number ')

(options, args) = parser .parse_args()

StartScan(options .target IP, options .port, options .threadNum)

这里打开了一个CentOS7的服务器作为目标,IP地址为192.168.61.62 ,服务器

 

 

 

开放了22 、80 、3306号端口,然后利用编写好的程序脚本对服务器进行端口扫 描,扫描结果如下所示:

760be2721a534575b6dabb4a9194cbcf.png

再对服务器进行范围端口的扫描,如下所示:

54583ff4529b46ba99c76b7b5afb6d26.png

对于开放端口探测,同样也可以借助Nmap库来实现,这里需要用到Nmap的- p参数。详细的代码此处不再赘述,读者可在4.2.1节的基础上进行修改。所需修  改的代码部分如下所示:

U

result = nm .scan(hosts=target IP, arguments= '-p '+str(targetPort))

测试效果如下:

dbb30b6867b9419ea7dd8dba8ee52570.png

 

 

 

 

 

 

4.2.5    服务识别

 

在渗透测试的过程中,服务识别是一个很重要的环节。如果能识别出目标主 机的服务、版本等信息,对于渗透测试将有重要帮助。对于入侵者来说,发现这 些运行在目标上的服务,就可以利用这些软件上的漏洞入侵目标;对于网络安全 的维护者来说,也可以提前发现系统的漏洞,从而预防这些入侵行为。

很多扫描工具都采用了一种十分简单的方式,就是根据端口判断服务类型,

因为通常常见的服务都会运行在固定的端口上(见表4-1~表4-7),例如,FTP服 务总会运行在21号端口上,HTTP服务运行在80号端口上。但是利用该方式进行

服务识别存在明显的缺陷,很多人会将服务运行在其他端口上,例如,将本来运  行在23号端口上的Telnet运行在22号端口上,这样就会误以为这是一个SSH服务, 进而增加不必要的工作量。由于很多软件在连接之后都会提供一个表明自身信息  的banner ,在这里我们可以根据获取的banner信息对运行的服务类型进行判断,进 而可以确定开放端口对应的服务类型及版本号。

表4-1    文件共享服务端口

主动信息搜集_第14张图片

表4-2    远程连接服务端口

主动信息搜集_第15张图片

表4-3    Web应用服务端口

 

 

 

 

 

主动信息搜集_第16张图片

表4-4    数据库服务端口

主动信息搜集_第17张图片

表4-5    邮件服务端口

2988816cb13c4f1f8dfa5e194661e391.png

表4-6    网络常见协议端口主动信息搜集_第18张图片

表4-7    特殊服务端口

 

主动信息搜集_第19张图片

 

 

 

因此,可以向目标开放的端口发送探针数据包,根据目标主机返回的banner   信息与存储总结的banner信息进行比对,进而确定运行的服务类型。著名的Nmap 扫描工具就是采用了这种方法,它包含一个十分强大的banner数据库,而且这个  库仍在不断完善中。接下来按照上面介绍的思路来编写对目标服务进行扫描的程 序。

1)导入程序代码所应用到的模块:time 、optparse 、socket和re 。time模块主 要用于产生延迟时间,optparse模块用于生成命行参数,socket模块用于产生TCP 请求,re模块为正则表达式模块,与指纹信息进行有效匹配,进而确定服务类

型。SIGNS为指纹库,用于对目标

from optparse import OptionParser

import

import

import

SIGNS = (

# 协议 | 版本 | 关键字

b 'FTP |FTP |^220 .*FTP ',

b 'MySQL |MySQL |mysql_native_password ',

b 'oracle-https |^220- ora ',

b 'Telnet|Telnet|Telnet ',

b 'Telnet|Telnet|^\r\n%connection closed by remote host!\x00$ ',

b 'VNC |VNC |^RFB ',

b 'IMAP |IMAP |^\* OK .*?IMAP ',

b 'POP |POP |^\+OK .*? ',

b 'SMTP |SMTP |^220 .*?SMTP ',

b 'Kangle |Kangle |HTTP .*kangle ',

b 'SMTP |SMTP |^554 SMTP ',

b 'SSH |SSH |^SSH- ',

b 'HTTPS |HTTPS |Location: https ',

b 'HTTP |HTTP |HTTP/1 .1 ',

b 'HTTP |HTTP |HTTP/1 .0 ',

)

 

 

 

 

 

 

def main() :

parser = OptionParser("Usage:%prog -i  ")   # 输出帮助信息

parser .add_option( '-i ',type= 'string ',dest= 'IP ',help= 'specify target host ') # 获取IP地址参数

parser .add_option( '-p ', type= 'string ', dest= 'PORT ', help= 'specify target

host ')  # 获取IP地址参数

options,args = parser .parse_args()

ip = options .IP

port = options .PORT

print("Scan report for "+ip+"\n")

for line in port.split( ', ') :

request(ip,line)

time .sleep(0 .2)

print("\nScan finished!. . .\n")

if __name__ == "__main__" :

try:

main()

except Keyboard Interrupt :

print("interrupted by user, killing all threads . . .")

 

3)在request() 函数中,首先调用sock.connect() 函数探测目标主机端口  是否开放,如果端口开放,则利用sock.sendall() 函数将PROBE探针发送给目标 端口。sock.recv() 函数用于接收返回的指纹信息,并将指纹信息及端口发送到 regex() 函数。

def request(ip,port) :

response = ' '

PROBE = 'GET / HTTP/1 .0\r\n\r\n '

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.settimeout(10)

result = sock.connect_ex((ip, in t(port)))

if result == 0:

try:

sock.sendall(PROBE .encode())

response = sock.recv(256)

if response:

regex(response, port)

except(ConnectionResetError,socket.timeout) :

pass

else:

pass

sock.close()

4)利用re.search() 函数将返回的banner信息与SIGNS包含的指纹信息进行 正则匹配,并将匹配到的结果输出。如果没有在SIGNS中找到相匹配的信息,则 输出Unrecognized。

def regex(response, port) :

text = ""

if re .search(b '502 Bad Gateway ', response) :</p> <p style="margin-left:.0001pt;text-align:left;">proto = {"Service failed to access !!"}</p> <p style="margin-left:.0001pt;text-align:left;">for pattern in SIGNS:</p> <p style="margin-left:.0001pt;text-align:left;">pattern = pattern .split(b ' | ')</p> <p style="margin-left:.0001pt;text-align:left;">if re .search(pattern[-1], response, re .IGNORECASE) :</p> <p style="margin-left:.0001pt;text-align:left;">proto = "["+port+"]" + " open " + pattern[1] .decode()</p> <p style="margin-left:.0001pt;text-align:left;">break</p> <p style="margin-left:.0001pt;text-align:left;">else:</p> <p style="margin-left:.0001pt;text-align:left;">proto = "["+port+"]" + " open " + "Unrecognized"</p> <p style="margin-left:.0001pt;text-align:left;">print(proto)</p> </div> <p> </p> <div> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <table style="width:468pt;"> <tbody> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;"> </p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;">端口服务版本的识别实现起来也是比较困难的, 目前市面上能提供相关服务  的软件也非常多,而且每个软件也会出现多个版本。下面借助Nmap库来实现对主 机端口服务的探测,这里还需要用到Nmap的-sV参数。详细的代码此处就不再赘  述,读者可在4.2.1节的基础上进行修改,所需修改的代码部分如下所示:</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:36.9pt;">(2) print("[{} :{}] : [{} :{}]" .format(targetPort, port_infor[ 'state '] , port_ infor[ 'name '], port_infor[ 'product '])</p> </td> </tr> </tbody> </table> <p style="margin-left:.0001pt;text-align:left;">测试效果如下:</p> </div> <p> </p> <div> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;">4.2.6    系统识别</p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;">识别出目标主机操作系统的类型和版本,可以大量减少不必要的测试成本, 缩小测试范围,更精确地针对目标进行渗透测试。</p> <p style="margin-left:.0001pt;text-align:left;">但是判断目标的操作系统并非一件简单的事情。因为现在的操作系统类型繁 多,仅Windows和Linux就有包含了许多衍生系统,同时,现今的防火墙、路由  器、智能设备等都有其自带的操作系统,所以需要精确判断目标操作系统的类型 并非易事。 目前主要通过“指纹识别” 的方式来对目标的操作系统来进行猜测。检 测的方法一般分为两种:主动式探测和被动式探测。</p> <p style="margin-left:.0001pt;text-align:justify;">(1)主动式探测:向目标主机发送一段特定的数据包,根据目标主机对数  据包做出的回应进行分析,判断目标主机中可能的操作系统类型。与被动式探测 相比,主动式获取的结果更加精确,但也容易触发目标安全系统的警报。</p> <p style="margin-left:.0001pt;text-align:justify;">(2)被动式探测:通过工具嗅探、记录、分析数据包流。根据数据包信息  来分析目标主机的操作系统。与主动式探测相比,被动式探测的结果虽然不如主 动式探测精确,但是不容易被目标主机安全系统察觉。</p> <p style="margin-left:.0001pt;text-align:left;">主机识别的技术原理:Windows操作系统与Linux操作系统的TCP/IP实现方式 并不相同,导致两种系统对特定格式的数据包会有不同的响应结果,包括响应数 据包的内容、响应时间等,形成了操作系统的指纹。通常情况下,可在对目标主 机进行ping操作后,依据其返回的TTL值对系统类型进行判断,Windows系统的  TTL起始值为128 ,Linux系统的TTL起始值为64 ,且每经过一跳路由,TTL值减  1。</p> <p style="margin-left:.0001pt;text-align:left;">Windows的TTL返回值如下:</p> <p style="margin-left:.0001pt;text-align:left;"><a href="http://img.e-com-net.com/image/info8/c12b8aaefea34a6e9d0a216831079c7c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c12b8aaefea34a6e9d0a216831079c7c.jpg" alt="主动信息搜集_第20张图片" width="650" height="117" style="border:1px solid black;"></a></p> <p style="margin-left:.0001pt;text-align:left;">Linux的TTL返回值如下:</p> </div> <p> </p> <div> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <a href="http://img.e-com-net.com/image/info8/a8485d8a6170445da4bee91ed63f2147.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a8485d8a6170445da4bee91ed63f2147.jpg" alt="主动信息搜集_第21张图片" width="650" height="137" style="border:1px solid black;"></a> <p style="margin-left:.0001pt;text-align:left;">根据按照目标主机返回的响应数据包中的TTL值来判断操作系统类型的原 理,可编写Python程序实现自动化,详细过程如下所示。</p> <p style="margin-left:.0001pt;text-align:left;">1)导入程序代码所应用的模块:optparse 、os和re 。optparse用于生成命行参 数;os用于执行系统命令;re为正则表达式模块,用于匹配返回的TTL值。</p> <p style="margin-left:.0001pt;text-align:left;"> </p> <table style="width:468pt;"> <tbody> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:16.4pt;">#!/usr/bin/python3 .7</p> <p style="margin-left:16.4pt;">#!coding:utf-8</p> <p style="margin-left:16.75pt;">from optparse import OptionParser</p> <p style="margin-left:16.75pt;">import os</p> <p style="margin-left:16.75pt;">import re</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;">2)利用optparse模块生成命令行参数化形式,对用户输入的参数进行接收和 批量处理,最后将处理后的IP地址传入ttl_scan() 函数。</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:16.75pt;">def main() :</p> <p style="margin-left:37.05pt;">parser = OptionParser("Usage:%prog -i <target host> ")   # 输出帮助信息</p> <p style="margin-left:56.65pt;">parser .add_option( '-i ',type= 'string ',dest= 'IP ',help= 'specify target host ') # 获取IP地址参数</p> <p style="margin-left:36.85pt;">options,args = parser .parse_args()</p> <p style="margin-left:36.9pt;">ip = options .IP</p> <p style="margin-left:37.1pt;">ttl_scan(ip)</p> <p style="margin-left:16.75pt;">if __name__ == "__main__" :</p> <p style="margin-left:36.7pt;">main()</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;">3)调用os.popen() 函数执行ping命令,并将返回的结果通过正则表达式识</p> <p style="margin-left:.0001pt;text-align:left;">别,提取出TTL值。当TTL值小于等于64时,操作系统为Linux类型,输 出“xx.xx.xx.xx is Linux/UNIX” ,否则输出“xx.xx.xx.xx is Windows”。</p> </td> </tr> </tbody> </table> <p style="margin-left:.0001pt;text-align:left;">def ttl_scan(ip) :</p> <p style="margin-left:.0001pt;text-align:left;">ttlstrmatch = re .compile(r 'ttl=\d+ ')</p> <p style="margin-left:.0001pt;text-align:left;">ttlnummatch = re .compile(r '\d+ ')</p> <p style="margin-left:.0001pt;text-align:left;">result = os .popen("ping -c 1 "+ip)</p> <p style="margin-left:.0001pt;text-align:left;">res = result.read()</p> <p style="margin-left:.0001pt;text-align:left;">for line in res .splitlines() :</p> <p style="margin-left:.0001pt;text-align:left;">result = ttlstrmatch.findall(line)</p> <p style="margin-left:.0001pt;text-align:left;">if result :</p> <p style="margin-left:.0001pt;text-align:left;">ttl = ttlnummatch.findall(result[0])</p> <p style="margin-left:.0001pt;text-align:left;">if in t(ttl[0]) <= 64:  # 判断目标主机响应包中TTL值是否小于等于64</p> <p style="margin-left:.0001pt;text-align:left;">print("%s  is Linux/UNIX"%ip)  # TTL≤64时为Linux/UNIX系统 else:</p> <p style="margin-left:.0001pt;text-align:left;">print("%s is Windows"%ip)      # 反之为Windows系统</p> <p style="margin-left:.0001pt;text-align:left;">else:</p> <p style="margin-left:.0001pt;text-align:left;">pass</p> </div> <p> </p> <div> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <table style="width:468pt;"> <tbody> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;">运行结果如下:</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"><a href="http://img.e-com-net.com/image/info8/43550f13e1d04f5990f0b9aeab182b44.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/43550f13e1d04f5990f0b9aeab182b44.jpg" alt="9937f9b7510d41d4b039231045803384.png" width="650" height="73"></a></td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:.0001pt;text-align:left;">当然,这里也可以借助Nmap库来实现操作系统类型识别的功能,通过Nmap 的-O参数对目标主机操作进行系统识别,代码如下所示:</p> </td> </tr> <tr> <td style="vertical-align:top;width:468pt;"> <p style="margin-left:17.15pt;">result = nm .scan(hosts=target IP, arguments= '-O ')</p> </td> </tr> </tbody> </table> <p style="margin-left:.0001pt;text-align:left;">借助Nmap库我们可以很轻松地完成一个主动式系统探测工具,而且其判断的 结果在实际运用中也非常具有参考价值。</p> <p style="margin-left:.0001pt;text-align:left;">运行结果如下:</p> <a href="http://img.e-com-net.com/image/info8/5d2b19c8d8b6490c9d10494619abce3e.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/5d2b19c8d8b6490c9d10494619abce3e.jpg" alt="主动信息搜集_第22张图片" width="650" height="110" style="border:1px solid black;"></a> </div> <p> </p> <div> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;">4.2.7    敏感目录探测</p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:justify;">资源发现属于信息搜集的一部分,善于发现隐藏的信息,如隐藏目录、隐藏 文件等,可提高渗透测试的全面细致性。本节将用Python实现敏感目录发现。在 渗透测试过程中,资源发现是极其重要的一环。具备好的资源发现能力能够令整 个工作事半功倍。</p> <p style="margin-left:.0001pt;text-align:justify;">在渗透测试过程中进行目录扫描是很有必要的,例如,当发现开发过程中未 关闭或忘记关闭的页面,可能就会发现许多可以利用的信息。下面我们编写一个 基于字典的目录扫描脚本。</p> <p style="margin-left:.0001pt;text-align:left;">1)要进行网页目录扫描,需要进行网页访问,所以先导入requests模块备 用,然后等待用户输入url和字典:</p> <p style="margin-left:.0001pt;text-align:left;"> </p> <table style="width:469.25pt;"> <tbody> <tr> <td style="vertical-align:top;width:469.25pt;"> <p style="margin-left:16.75pt;">import requests</p> <p style="margin-left:16.95pt;">headers = {</p> <p style="margin-left:16.85pt;">"User-Agent" : "Mozilla/5 .0 (Windows NT 6 .1; WOW64; rv:6 .0) Gecko/20100101 Firefox/6 .0" }</p> <p style="margin-left:16.95pt;">url = input("url : ")</p> <p style="margin-left:16.95pt;">txt = input( 'php .txt ')</p> </td> </tr> <tr> <td style="vertical-align:top;width:469.25pt;"> <p style="margin-left:.0001pt;text-align:left;">2)当用户没有输入字典时,默认打开根目录的php.txt ,后将字典中的内容 放进队列中:</p> </td> </tr> <tr> <td style="vertical-align:top;width:469.25pt;"> <p style="margin-left:16.95pt;">url_list = []</p> <p style="margin-left:16.75pt;">if txt == "" :</p> <p style="margin-left:37.1pt;">txt = "php .txt"</p> <p style="margin-left:16.95pt;">try:</p> <p style="margin-left:36.4pt;">with open(txt, 'r ') as f :</p> <p style="margin-left:57pt;">for a in f :</p> <p style="margin-left:77.1pt;">a = a .replace( '\n ', '')</p> <p style="margin-left:77.35pt;">url_list.append(a)</p> <p style="margin-left:57pt;">f.close()</p> <p style="margin-left:16.7pt;">except :</p> <p style="margin-left:37.05pt;">print("error!")</p> </td> </tr> <tr> <td style="vertical-align:top;width:469.25pt;"> <p style="margin-left:.0001pt;text-align:left;">3)将队列中的内容拼接到url中组成需要验证的地址,通过返回值判断是否 存在此目录:</p> <p style="margin-left:.0001pt;text-align:left;"> </p> </td> </tr> <tr> <td style="vertical-align:top;width:469.25pt;"> <p style="margin-left:16.75pt;">for li in url_list :</p> <p style="margin-left:36.85pt;">conn = "http://" + url +"/"+ li</p> <p style="margin-left:37.1pt;">try:</p> <p style="margin-left:62.5pt;">response = requests .get(conn,headers = headers)</p> <p style="margin-left:62.2pt;">print("%s  %s" % (conn, response))</p> <p style="margin-left:36.85pt;">except e:</p> <p style="margin-left:57.2pt;">print( '%s-------------%s ' %(conn, e .code))</p> </td> </tr> </tbody> </table> <p style="margin-left:.0001pt;text-align:left;"> </p> </div> <p> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;"> </p> <p style="margin-left:.0001pt;text-align:left;">至此,一个简单的目录扫描脚本就完成了。运行效果如下所示:</p> <p><a href="http://img.e-com-net.com/image/info8/f68fc93b6f8746fd8a80e89086aa8f18.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f68fc93b6f8746fd8a80e89086aa8f18.jpg" alt="主动信息搜集_第23张图片" width="650" height="183" style="border:1px solid black;"></a></p> <p> </p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1753943922737954816"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(笔记)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1943991261279088640.htm" title="C++ 11 Lambda表达式和min_element()与max_element()的使用_c++ lamda函数 min_element((1)" target="_blank">C++ 11 Lambda表达式和min_element()与max_element()的使用_c++ lamda函数 min_element((1)</a> <span class="text-muted">2401_84976182</span> <a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/c%E8%AF%AD%E8%A8%80/1.htm">c语言</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上CC++开发知识点,真正体系化!由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新如果你需要这些资料,可以戳这里获取#include#include#includeusingnamespacestd;boolcmp(int</div> </li> <li><a href="/article/1943983696184930304.htm" title="基于链家网的二手房数据采集清洗与可视化分析" target="_blank">基于链家网的二手房数据采集清洗与可视化分析</a> <span class="text-muted">Mint_Datazzh</span> <a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE/1.htm">项目</a><a class="tag" taget="_blank" href="/search/selenium/1.htm">selenium</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/1.htm">网络爬虫</a> <div>个人学习内容笔记,仅供参考。项目链接:https://gitee.com/rongwu651/lianjia原文链接:基于链家网的二手房数据采集清洗与可视化分析–笔墨云烟研究内容该课题的主要目的是通过将二手房网站上的存量与已销售房源,构建一个二手房市场行情情况与房源特点的可视化平台。该平台通过HTML架构和Echarts完成可视化的搭建。因此,该课题的主要研究内容就是如何利用相关技术设计并实现这样</div> </li> <li><a href="/article/1943983064304644096.htm" title="算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题" target="_blank">算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题</a> <span class="text-muted"></span> <div>在计算机科学和数学领域,蒙特卡洛算法(MonteCarloAlgorithm)以其独特的随机抽样思想,成为解决复杂问题的有力工具。从圆周率的计算到金融风险评估,从物理模拟到人工智能,蒙特卡洛算法都发挥着不可替代的作用。本文将深入剖析蒙特卡洛算法的思想、解题思路,结合实际应用场景与Java代码实现,并融入考研408的相关考点,穿插图片辅助理解,帮助你全面掌握这一重要算法。蒙特卡洛算法的基本概念蒙特卡</div> </li> <li><a href="/article/1943983064719880192.htm" title="分布式学习笔记_04_复制模型" target="_blank">分布式学习笔记_04_复制模型</a> <span class="text-muted">NzuCRAS</span> <a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>常见复制模型使用复制的目的在分布式系统中,数据通常需要被分布在多台机器上,主要为了达到:拓展性:数据量因读写负载巨大,一台机器无法承载,数据分散在多台机器上仍然可以有效地进行负载均衡,达到灵活的横向拓展高容错&高可用:在分布式系统中单机故障是常态,在单机故障的情况下希望整体系统仍然能够正常工作,这时候就需要数据在多台机器上做冗余,在遇到单机故障时能够让其他机器接管统一的用户体验:如果系统客户端分布</div> </li> <li><a href="/article/1943983063352537088.htm" title="算法学习笔记:15.二分查找 ——从原理到实战,涵盖 LeetCode 与考研 408 例题" target="_blank">算法学习笔记:15.二分查找 ——从原理到实战,涵盖 LeetCode 与考研 408 例题</a> <span class="text-muted">呆呆企鹅仔</span> <a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0/1.htm">算法学习</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E8%80%83%E7%A0%94/1.htm">考研</a><a class="tag" taget="_blank" href="/search/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/1.htm">二分查找</a> <div>在计算机科学的查找算法中,二分查找以其高效性占据着重要地位。它利用数据的有序性,通过不断缩小查找范围,将原本需要线性时间的查找过程优化为对数时间,成为处理大规模有序数据查找问题的首选算法。二分查找的基本概念二分查找(BinarySearch),又称折半查找,是一种在有序数据集合中查找特定元素的高效算法。其核心原理是:通过不断将查找范围减半,快速定位目标元素。与线性查找逐个遍历元素不同,二分查找依赖</div> </li> <li><a href="/article/1943963776244051968.htm" title="入门html这篇文章就够了" target="_blank">入门html这篇文章就够了</a> <span class="text-muted">ξ流ぁ星ぷ132</span> <a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>HTML笔记文章目录HTML笔记html介绍什么是htmlhtml的作用HTML标签介绍常用标签标签and标签and标签u标签del删除线br标签用于换行pre标签,预处理标签span标签div标签sub标签andsup标签hr标签h1,h2...h6标签:HTML5中的语义标签:特殊字符img标签a标签第一种用法:超链接第二种用法:锚点video标签表格标签:form标签input标签selec</div> </li> <li><a href="/article/1943956589136375808.htm" title="OKHttp3源码分析——学习笔记" target="_blank">OKHttp3源码分析——学习笔记</a> <span class="text-muted">Sincerity_</span> <a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81%E7%9B%B8%E5%85%B3/1.htm">源码相关</a><a class="tag" taget="_blank" href="/search/Okhttp/1.htm">Okhttp</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/1.htm">源码解析</a><a class="tag" taget="_blank" href="/search/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/1.htm">读书笔记</a><a class="tag" taget="_blank" href="/search/httpclient/1.htm">httpclient</a><a class="tag" taget="_blank" href="/search/cache/1.htm">cache</a> <div>文章目录1.HttpClient与HttpUrlConnection的区别2.OKHttp源码分析使用步骤:dispatcher任务调度器,(后面有详细说明)Request请求RealCallAsyncCall3.OKHttp架构分析1.异步请求线程池,Dispather2.连接池清理线程池-ConnectionPool3.缓存整理线程池DisLruCache4.Http2异步事务线程池,http</div> </li> <li><a href="/article/1943926464663580672.htm" title="vue3面试题(个人笔记)" target="_blank">vue3面试题(个人笔记)</a> <span class="text-muted">武昌库里写JAVA</span> <a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB%E4%B8%8E%E8%A7%A3%E6%9E%90/1.htm">面试题汇总与解析</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1/1.htm">课程设计</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>vue3比vue2有什么优势?性能更好,打包体积更小,更好的ts支持,更好的代码组织,更好的逻辑抽离,更多的新功能。描述Vue3生命周期CompositionAPI的生命周期:onMounted()onUpdated()onUnmounted()onBeforeMount()onBeforeUpdate()onBeforeUnmount()onErrorCaptured()onRenderTrac</div> </li> <li><a href="/article/1943920162180755456.htm" title="Python学习笔记5|条件语句和循环语句" target="_blank">Python学习笔记5|条件语句和循环语句</a> <span class="text-muted">iamecho9</span> <a class="tag" taget="_blank" href="/search/Python%E4%BB%8E0%E5%88%B01%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.htm">Python从0到1学习笔记</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>一、条件语句条件语句用于根据不同的条件执行不同的代码块。1、if语句基本语法:if布尔型语句1:代码块#语句1为True时执行的代码示例:age=int(input("请输入你的年龄:"))ifage>=18:print("你已成年")2、if-else语句如果if条件不成立,则执行else代码块:if布尔型语句1:代码块#语句1为True时执行的代码else:代码块#语句1为False时执行的代</div> </li> <li><a href="/article/1943914995217657856.htm" title="swagger【个人笔记】" target="_blank">swagger【个人笔记】</a> <span class="text-muted">撰卢</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>文章目录swagger导入mave坐标在配置类(WebMvcConfiguration)中加入knife4j相关配置设置静态资源映射,主要是让拦截器放行swagger常用注解@Api(tags="\[描述这个类的作用]")@ApiModel(description="\[描述这个类的作用]")@ApiModelProPerty("描述这个类的作用")@ApiOperation("\[描述方法的作用</div> </li> <li><a href="/article/1943913603195269120.htm" title="【个人笔记】负载均衡" target="_blank">【个人笔记】负载均衡</a> <span class="text-muted">撰卢</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/1.htm">负载均衡</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>文章目录nginx反向代理的好处负载均衡负载均很的配置方式均衡负载的方式nginx反向代理的好处提高访问速度进行负载均衡保证后端服务安全负载均衡负载均衡,就是把大量的请求按照我们指定的方式均衡的分配给集群中的每台服务器负载均很的配置方式upstreamwebservers{server192.168.100.128:8080server192.168.100.129:8080}server{lis</div> </li> <li><a href="/article/1943881336846610432.htm" title="在 Obsidian 中本地使用 DeepSeek — 无需互联网!" target="_blank">在 Obsidian 中本地使用 DeepSeek — 无需互联网!</a> <span class="text-muted">知识大胖</span> <a class="tag" taget="_blank" href="/search/NVIDIA/1.htm">NVIDIA</a><a class="tag" taget="_blank" href="/search/GPU%E5%92%8C%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B/1.htm">GPU和大语言模型开发教程</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/deepseek/1.htm">deepseek</a> <div>简介您是否想在Obsidian内免费使用类似于ChatGPT的本地LLM?如果是,那么本指南适合您!我将引导您完成在Obsidian中安装和使用DeepSeek-R1模型的确切步骤,这样您就可以在笔记中拥有一个由AI驱动的第二大脑。推荐文章《24GBGPU中的DeepSeekR1:UnslothAI针对671B参数模型进行动态量化》权重1,DeepSeek类《在RaspberryPi上运行语音识别</div> </li> <li><a href="/article/1943848048312512512.htm" title="5G标准学习笔记14 - CSI--RS概述" target="_blank">5G标准学习笔记14 - CSI--RS概述</a> <span class="text-muted">刘孬孬沉迷学习</span> <a class="tag" taget="_blank" href="/search/5G/1.htm">5G</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E4%B8%8E%E9%80%9A%E4%BF%A1/1.htm">信息与通信</a> <div>5G标准学习笔记14-CSI–RS概述大家好~,这里是刘孬孬,今天带着大家一起学习一下5GNR中一个非常非常重要的参考信号------------------CSI-RS信号,CSI-RS不是持续发送,UE只能在网络明确配置了CSI-RS的情况下才能使用其进行信道测量。前言对于CSI-RS,肯定还离不开前面所说的CSI(channelstateinformation),前面也讲过CSI对于MIMO</div> </li> <li><a href="/article/1943847921355124736.htm" title="5G标准学习笔记06-基于AI/ML波束管理" target="_blank">5G标准学习笔记06-基于AI/ML波束管理</a> <span class="text-muted">刘孬孬沉迷学习</span> <a class="tag" taget="_blank" href="/search/5G/1.htm">5G</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>5G标准学习笔记06-基于AI/ML波束管理前言前面对于孬孬学习了波束管理的概述,下面要进一步来看一下传统波束管理和现在3GPP中推动的AL/ML波束管理之前的区别联系。一、传统波束管理方法流程传统BM流程主要包括以下步骤:波束扫描(BeamSweeping):gNB通过顺序发送多个窄波束(SSB或CSI-RS),覆盖整个服务区域,UE测量每个波束的信号质量(如L1-RSRP或L1-SINR)。波</div> </li> <li><a href="/article/1943847795194654720.htm" title="5G标准学习笔记03- CSI 反馈增强概述" target="_blank">5G标准学习笔记03- CSI 反馈增强概述</a> <span class="text-muted">刘孬孬沉迷学习</span> <a class="tag" taget="_blank" href="/search/5G/1.htm">5G</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>5G标准学习笔记03-CSI反馈增强概述大家好,最近在研究AI/ML3gpp标准NR空口的有关内容,后面可能会给大家介绍一下对应的有关内容AI/ML在3GPP标准中的研究进展在AI/ML在NR空口的应用中,对应标准主要聚焦了3个case进行讨论研究分别是:CSI反馈增强;波束管理;定位精度增强;这三个内容可能比较涉及RAN1/2的具体内容,后面会基于这个进行一定的介绍。今天主要是主要介绍CSI反馈</div> </li> <li><a href="/article/1943847035476176896.htm" title="运维笔记<4> xxl-job打通" target="_blank">运维笔记<4> xxl-job打通</a> <span class="text-muted">GeminiJM</span> <a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/xxl-job/1.htm">xxl-job</a> <div>新的一天,来点新的运维业务,今天是xxl-job的打通其实在非集群中,xxl-job的使用相对是比较简单的,相信很多人都有使用的经验这次我们的业务场景是在k8s集群中,用xxl-job来做定时调度加上第一次倒腾,也是遇到了不少问题,在这里做一些记录1.xxl-job的集群安装首先是xxl-job的集群安装先贴上xxl-jobsql初始化文件的地址:xxl-job/doc/db/tables_xxl</div> </li> <li><a href="/article/1943834174582484992.htm" title="两台pc如何高速度传输大文件" target="_blank">两台pc如何高速度传输大文件</a> <span class="text-muted">费城之鹰</span> <a class="tag" taget="_blank" href="/search/%E5%85%B6%E4%BB%96/1.htm">其他</a><a class="tag" taget="_blank" href="/search/%E4%B8%A4%E5%8F%B0%E7%94%B5%E8%84%91%E9%AB%98%E9%80%9F%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6/1.htm">两台电脑高速传输文件</a><a class="tag" taget="_blank" href="/search/%E5%B1%80%E5%9F%9F%E7%BD%91/1.htm">局域网</a><a class="tag" taget="_blank" href="/search/%E4%B8%8D%E9%80%82%E7%94%A8U%E7%9B%98%E4%BC%A0%E8%BE%93%E8%B5%84%E6%96%99/1.htm">不适用U盘传输资料</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BA%BF%E7%9B%B4%E8%BF%9E%E4%B8%A4%E5%8F%B0%E7%94%B5%E8%84%91%E4%BC%A0%E8%B5%84%E6%96%99/1.htm">网线直连两台电脑传资料</a> <div>今天笔记本跑一个大一点的项目,8G的内存直接100%,i5的CPU直接75%并且在超频工作了,原本1.6Ghz的频率直接飙到了3.8Ghz,由于项目性质原因,采用的是公司配的笔记本,但是年初采购的联想E480,还在三包时间段内,公司不允许拆机增加内存,只能换一台新的台式机,听起来挺爽,有新设备,但是办公区域不准使用U盘这一类的存储设备,这就蛋疼了,大半年了项目代码,资料全在这个不够用的笔记本里,问</div> </li> <li><a href="/article/1943833920403468288.htm" title="学习笔记(33):matplotlib绘制简单图表-绘制混淆矩阵热图" target="_blank">学习笔记(33):matplotlib绘制简单图表-绘制混淆矩阵热图</a> <span class="text-muted">宁儿数据安全</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/matplotlib/1.htm">matplotlib</a> <div>学习笔记(33):matplotlib绘制简单图表-绘制混淆矩阵热图一、绘制混淆矩阵热图代码解析1.1、导入必要的库importmatplotlib.pyplotaspltfromsklearn.metricsimportconfusion_matriximportseabornassnsmatplotlib.pyplot:Python中最常用的绘图库,用于创建各种图表confusion_matr</div> </li> <li><a href="/article/1943830011131785216.htm" title="玩转Docker | 使用Docker部署NotepadMX笔记应用程序" target="_blank">玩转Docker | 使用Docker部署NotepadMX笔记应用程序</a> <span class="text-muted">心随_风动</span> <a class="tag" taget="_blank" href="/search/%E7%8E%A9%E8%BD%ACDocker/1.htm">玩转Docker</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/eureka/1.htm">eureka</a> <div>玩转Docker|使用Docker部署NotepadMX笔记应用程序前言一、NotepadMX介绍工具简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署NotepadMX服务下载NotepadMX镜像编辑部署文件创建容器检查容器状态检查服务端口安全设置四、访问NotepadMX服务访问NotepadMX首页设置访问验证编辑笔记总结前言在如今快节奏的工作与学习中,一</div> </li> <li><a href="/article/1943824841912152064.htm" title="【前端】异步任务风控验证与轮询机制技术方案(通用笔记版)" target="_blank">【前端】异步任务风控验证与轮询机制技术方案(通用笔记版)</a> <span class="text-muted"></span> <div>一、背景场景在某类生成任务中,例如用户点击“执行任务”按钮后触发一个较耗时的后端操作(如生成报告、渲染图像、转码视频等),由于其调用了模型、渲染服务或需要较长处理时间,为了防止接口被频繁恶意调用,系统需要加入风控验证机制。此外,因任务处理为异步,前端无法立即获得最终结果,因此需通过轮询方式定期查询任务状态,等待任务完成后展示结果。二、整体流程说明1.用户点击“执行任务”按钮:前端调用风控接口/ap</div> </li> <li><a href="/article/1943814121778638848.htm" title="数据分析案例-电脑笔记本价格数据可视化分析3" target="_blank">数据分析案例-电脑笔记本价格数据可视化分析3</a> <span class="text-muted">艾派森</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E7%94%B5%E8%84%91/1.htm">电脑</a> <div>‍♂️个人主页:@艾派森的个人主页✍作者简介:Python学习者希望大家多多支持,我们一起进步!如果文章对你有帮助的话,欢迎评论点赞收藏加关注+目录1.项目背景2.数据集介绍3.技术工具</div> </li> <li><a href="/article/1943805168290164736.htm" title="LLaMA 学习笔记" target="_blank">LLaMA 学习笔记</a> <span class="text-muted">AI算法网奇</span> <a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E5%9F%BA%E7%A1%80/1.htm">深度学习基础</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a> <div>目录LLaMA模型结构:模型微调手册:推理示例:指定位置加载模型测试ok:模型下载:llama-stack下载modelscope下载LLaMA优化技术RMSNormSwiGLU激活函数旋转位置编码(RoPE)LLaMA模型结构:llama3结构详解-CSDN博客模型微调手册:大模型微调LLaMA详细指南(准备环境、数据、配置微调参数+微调过程)_llama微调-CSDN博客显存占用:FP16/B</div> </li> <li><a href="/article/1943802516584067072.htm" title="BOOT_KEY按键(学习笔记)" target="_blank">BOOT_KEY按键(学习笔记)</a> <span class="text-muted">小高Baby@</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>先来让我们了解一下GPIO是什么吧,它在单片机中也有很重要的作用,接下来我们来看看吧。esp32C3是QFN32封装(一种集成电路(IC)封装类型),GPIO引脚一共有22个,从GPIO-0到GPIO-21。从理论上来说,所有的IO引脚都可以复用为任何外设功能,但有些引脚用作连接芯片内部FLASH或者外部FLASH功能时,官方不建议用作其它用途。esp32c3的GPIO,可以用作输入、输出,可以配</div> </li> <li><a href="/article/1943794071042584576.htm" title="多线程在Java项目中的使用案例(笔记)" target="_blank">多线程在Java项目中的使用案例(笔记)</a> <span class="text-muted">车车不吃香菇</span> <a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>多线程在Java项目中的使用案例(笔记)实现runnable接口@OverridepublicBooleanaddMeetingExpertIds(MeetAddExpertDtomeetAddExpertDto,LonguserId){//会议关联到专家//如果需要发给专家newThread(newRunnable(){@Overridepublicvoidrun(){try{if(meetAd</div> </li> <li><a href="/article/1943783227026108416.htm" title="【机器学习笔记Ⅰ】9 特征缩放" target="_blank">【机器学习笔记Ⅰ】9 特征缩放</a> <span class="text-muted">巴伦是只猫</span> <a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a> <div>特征缩放(FeatureScaling)详解特征缩放是机器学习数据预处理的关键步骤,旨在将不同特征的数值范围统一到相近的尺度,从而加速模型训练、提升性能并避免某些特征主导模型。1.为什么需要特征缩放?(1)问题背景量纲不一致:例如:特征1:年龄(范围0-100)特征2:收入(范围0-1,000,000)梯度下降的困境:量纲大的特征(如收入)会导致梯度更新方向偏离最优路径,收敛缓慢。量纲小的特征(如</div> </li> <li><a href="/article/1943767479650152448.htm" title="Kotlin学习笔记" target="_blank">Kotlin学习笔记</a> <span class="text-muted">qq_26907861</span> <div>1.Val和Varval:用于声明不可变量,不可变是指引用不可变;var:用于声明可变的变量;packagehello//可选的包头funmain(args:Array){//包级可见的函数,接受一个字符串数组作为参数vala="不可变的变量"//不可变的变量varn=2//可变println(a)println(n)}2.fun函数Kotlin中的函数可以这样声明:fun函数名(参数列表):返回</div> </li> <li><a href="/article/1943765965552545792.htm" title="扔物线--Kotlin协程训练营2期-2" target="_blank">扔物线--Kotlin协程训练营2期-2</a> <span class="text-muted"></span> <div>笔记仅做自己学习用,方便自己复习知识。若正好可以帮助到Viewer,万分欣喜~若博客侵权,扔物线大大不允许放上面,麻烦告知本文是扔物线Kotlin第二期协程训练营的第二篇文章没看过第一篇文章的可以先看第一篇:https://blog.csdn.net/bluerheaven/article/details/106969835目录一、Retrofit对协程的支持二、Retrofit和RxJava的结</div> </li> <li><a href="/article/1943762687385202688.htm" title="20250707-3-Kubernetes 核心概念-有了Docker,为什么还用K8s_笔记" target="_blank">20250707-3-Kubernetes 核心概念-有了Docker,为什么还用K8s_笔记</a> <span class="text-muted">Andy杨</span> <a class="tag" taget="_blank" href="/search/CKA-%E4%B8%93%E6%A0%8F/1.htm">CKA-专栏</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>一、Kubernetes核心概念1.有了Docker,为什么还用Kubernetes1)企业需求独立性问题:Docker容器本质上是独立存在的,多个容器跨主机提供服务时缺乏统一管理机制负载均衡需求:为提高业务并发和高可用,企业会使用多台服务器部署多个容器实例,但Docker本身不具备负载均衡能力管理复杂度:随着Docker主机和容器数量增加,面临部署、升级、监控等统一管理难题运维效率:单机升</div> </li> <li><a href="/article/1943758776741982208.htm" title="20250707-4-Kubernetes 集群部署、配置和验证-K8s基本资源概念初_笔记" target="_blank">20250707-4-Kubernetes 集群部署、配置和验证-K8s基本资源概念初_笔记</a> <span class="text-muted"></span> <div>一、kubeconfig配置文件文件作用:kubectl使用kubeconfig认证文件连接K8s集群生成方式:使用kubectlconfig指令生成核心字段:clusters:定义集群信息,包括证书和服务端地址contexts:定义上下文,关联集群和用户users:定义客户端认证信息current-context:指定当前使用的上下文二、Kubernetes弃用Docker1.弃用背景原因:</div> </li> <li><a href="/article/1943753358779150336.htm" title="麒麟系统离线安装docker" target="_blank">麒麟系统离线安装docker</a> <span class="text-muted"></span> <div>随着CentOS全面停服,国产操作系统会慢慢代替centos系统,在后续的项目中,项目部署的环境都必将是国产操作系统,本文就国产操作系统下如何离线安装docker,做下笔记分享一、材料准备1、国产操作系统麒麟10,arm64v82、dokcer部署包(版本:docker-18.09.tgz)3、部署docker脚本(docker.service),已经启动命令脚本(install.sh)二、编写d</div> </li> <li><a href="/article/105.htm" title="Js函数返回值" target="_blank">Js函数返回值</a> <span class="text-muted">_wy_</span> <a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/return/1.htm">return</a> <div>一、返回控制与函数结果,语法为:return 表达式;作用: 结束函数执行,返回调用函数,而且把表达式的值作为函数的结果 二、返回控制语法为:return;作用: 结束函数执行,返回调用函数,而且把undefined作为函数的结果 在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性</div> </li> <li><a href="/article/232.htm" title="MySQL 的 char 与 varchar" target="_blank">MySQL 的 char 与 varchar</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div> 今天发现,create table 时,MySQL 4.1有时会把 char 自动转换成 varchar 测试举例: CREATE TABLE `varcharLessThan4` ( `lastName` varchar(3) ) ; mysql> desc varcharLessThan4; +----------+---------+------+-</div> </li> <li><a href="/article/359.htm" title="Quartz——TriggerListener和JobListener" target="_blank">Quartz——TriggerListener和JobListener</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/TriggerListener/1.htm">TriggerListener</a><a class="tag" taget="_blank" href="/search/JobListener/1.htm">JobListener</a><a class="tag" taget="_blank" href="/search/quartz/1.htm">quartz</a> <div>转载请出自出处:http://eksliang.iteye.com/blog/2208624 一.概述 listener是一个监听器对象,用于监听scheduler中发生的事件,然后执行相应的操作;你可能已经猜到了,TriggerListeners接受与trigger相关的事件,JobListeners接受与jobs相关的事件。   二.JobListener监听器  j</div> </li> <li><a href="/article/486.htm" title="oracle层次查询" target="_blank">oracle层次查询</a> <span class="text-muted">18289753290</span> <a class="tag" taget="_blank" href="/search/oracle%EF%BC%9B%E5%B1%82%E6%AC%A1%E6%9F%A5%E8%AF%A2%EF%BC%9B%E6%A0%91%E6%9F%A5%E8%AF%A2/1.htm">oracle;层次查询;树查询</a> <div>.oracle层次查询(connect  by) oracle的emp表中包含了一列mgr指出谁是雇员的经理,由于经理也是雇员,所以经理的信息也存储在emp表中。这样emp表就是一个自引用表,表中的mgr列是一个自引用列,它指向emp表中的empno列,mgr表示一个员工的管理者, select   empno,mgr,ename,sal  from e</div> </li> <li><a href="/article/613.htm" title="通过反射把map中的属性赋值到实体类bean对象中" target="_blank">通过反射把map中的属性赋值到实体类bean对象中</a> <span class="text-muted">酷的飞上天空</span> <a class="tag" taget="_blank" href="/search/javaee/1.htm">javaee</a><a class="tag" taget="_blank" href="/search/%E6%B3%9B%E5%9E%8B/1.htm">泛型</a><a class="tag" taget="_blank" href="/search/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/1.htm">类型转换</a> <div>使用过struts2后感觉最方便的就是这个框架能自动把表单的参数赋值到action里面的对象中 但现在主要使用Spring框架的MVC,虽然也有@ModelAttribute可以使用但是明显感觉不方便。 好吧,那就自己再造一个轮子吧。 原理都知道,就是利用反射进行字段的赋值,下面贴代码 主要类如下:   import java.lang.reflect.Field; imp</div> </li> <li><a href="/article/740.htm" title="SAP HANA数据存储:传统硬盘的瓶颈问题" target="_blank">SAP HANA数据存储:传统硬盘的瓶颈问题</a> <span class="text-muted">蓝儿唯美</span> <a class="tag" taget="_blank" href="/search/HANA/1.htm">HANA</a> <div>SAPHANA平台有各种各样的应用场景,这也意味着客户的实施方法有许多种选择,关键是如何挑选最适合他们需求的实施方案。 在 《Implementing SAP HANA》这本书中,介绍了SAP平台在现实场景中的运作原理,并给出了实施建议和成功案例供参考。本系列文章节选自《Implementing SAP HANA》,介绍了行存储和列存储的各自特点,以及SAP HANA的数据存储方式如何提升空间压</div> </li> <li><a href="/article/867.htm" title="Java Socket 多线程实现文件传输" target="_blank">Java Socket 多线程实现文件传输</a> <span class="text-muted">随便小屋</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/socket/1.htm">socket</a> <div>        高级操作系统作业,让用Socket实现文件传输,有些代码也是在网上找的,写的不好,如果大家能用就用上。 客户端类:   package edu.logic.client; import java.io.BufferedInputStream; import java.io.Buffered</div> </li> <li><a href="/article/994.htm" title="java初学者路径" target="_blank">java初学者路径</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>学习Java有没有什么捷径?要想学好Java,首先要知道Java的大致分类。自从Sun推出Java以来,就力图使之无所不包,所以Java发展到现在,按应用来分主要分为三大块:J2SE,J2ME和J2EE,这也就是Sun ONE(Open Net Environment)体系。J2SE就是Java2的标准版,主要用于桌面应用软件的编程;J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;J2EE</div> </li> <li><a href="/article/1121.htm" title="APP推广" target="_blank">APP推广</a> <span class="text-muted">aoyouzi</span> <a class="tag" taget="_blank" href="/search/APP/1.htm">APP</a><a class="tag" taget="_blank" href="/search/%E6%8E%A8%E5%B9%BF/1.htm">推广</a> <div>一,免费篇 1,APP推荐类网站自主推荐 最美应用、酷安网、DEMO8、木蚂蚁发现频道等,如果产品独特新颖,还能获取最美应用的评测推荐。PS:推荐简单。只要产品有趣好玩,用户会自主分享传播。例如足迹APP在最美应用推荐一次,几天用户暴增将服务器击垮。 2,各大应用商店首发合作 老实盯着排期,多给应用市场官方负责人献殷勤。 3,论坛贴吧推广 百度知道,百度贴吧,猫扑论坛,天涯社区,豆瓣(</div> </li> <li><a href="/article/1248.htm" title="JSP转发与重定向" target="_blank">JSP转发与重定向</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/Java+Web/1.htm">Java Web</a><a class="tag" taget="_blank" href="/search/jsp%E8%BD%AC%E5%8F%91/1.htm">jsp转发</a> <div>  在servlet和jsp中我们经常需要请求,这时就需要用到转发和重定向;   转发包括;forward和include     例子;forwrad转发;  将请求装法给reg.html页面   关键代码;    req.getRequestDispatcher("reg.html</div> </li> <li><a href="/article/1375.htm" title="web.xml之jsp-config" target="_blank">web.xml之jsp-config</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/web.xml/1.htm">web.xml</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/jsp-config/1.htm">jsp-config</a> <div>1.作用:主要用于设定JSP页面的相关配置。 2.常见定义: <jsp-config> <taglib> <taglib-uri>URI(定义TLD文件的URI,JSP页面的tablib命令可以经由此URI获取到TLD文件)</tablib-uri> <taglib-location> TLD文件所在的位置 </div> </li> <li><a href="/article/1502.htm" title="JSF2.2 ViewScoped Using CDI" target="_blank">JSF2.2 ViewScoped Using CDI</a> <span class="text-muted">sunjing</span> <a class="tag" taget="_blank" href="/search/CDI/1.htm">CDI</a><a class="tag" taget="_blank" href="/search/JSF+2.2/1.htm">JSF 2.2</a><a class="tag" taget="_blank" href="/search/ViewScoped/1.htm">ViewScoped</a> <div>JSF 2.0 introduced annotation @ViewScoped; A bean annotated with this scope maintained its state as long as the user stays on the same view(reloads or navigation - no intervening views). One problem w</div> </li> <li><a href="/article/1629.htm" title="【分布式数据一致性二】Zookeeper数据读写一致性" target="_blank">【分布式数据一致性二】Zookeeper数据读写一致性</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a> <div>很多文档说Zookeeper是强一致性保证,事实不然。关于一致性模型请参考http://bit1129.iteye.com/blog/2155336    Zookeeper的数据同步协议 Zookeeper采用称为Quorum Based Protocol的数据同步协议。假如Zookeeper集群有N台Zookeeper服务器(N通常取奇数,3台能够满足数据可靠性同时</div> </li> <li><a href="/article/1756.htm" title="Java开发笔记" target="_blank">Java开发笔记</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/java%E5%BC%80%E5%8F%91/1.htm">java开发</a> <div>1、Map<key,value>的remove方法只能识别相同类型的key值   Map<Integer,String> map = new HashMap<Integer,String>(); map.put(1,"a"); map.put(2,"b"); map.put(3,"c"</div> </li> <li><a href="/article/1883.htm" title="图片黑色阴影" target="_blank">图片黑色阴影</a> <span class="text-muted">bozch</span> <a class="tag" taget="_blank" href="/search/%E5%9B%BE%E7%89%87/1.htm">图片</a> <div> .event{ padding:0;    width:460px;    min-width: 460px;    border:0px solid #e4e4e4;    height: 350px;    min-heig</div> </li> <li><a href="/article/2010.htm" title="编程之美-饮料供货-动态规划" target="_blank">编程之美-饮料供货-动态规划</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/1.htm">动态规划</a> <div> import java.util.Arrays; import java.util.Random; public class BeverageSupply { /** * 编程之美 饮料供货 * 设Opt(V’,i)表示从i到n-1种饮料中,总容量为V’的方案中,满意度之和的最大值。 * 那么递归式就应该是:Opt(V’,i)=max{ k * Hi+Op</div> </li> <li><a href="/article/2137.htm" title="ajax大参数(大数据)提交性能分析" target="_blank">ajax大参数(大数据)提交性能分析</a> <span class="text-muted">chenbowen00</span> <a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a><a class="tag" taget="_blank" href="/search/prototype/1.htm">prototype</a> <div>近期在项目中发现如下一个问题 项目中有个提交现场事件的功能,该功能主要是在web客户端保存现场数据(主要有截屏,终端日志等信息)然后提交到服务器上方便我们分析定位问题。客户在使用该功能的过程中反应点击提交后反应很慢,大概要等10到20秒的时间浏览器才能操作,期间页面不响应事件。 根据客户描述分析了下的代码流程,很简单,主要通过OCX控件截屏,在将前端的日志等文件使用OCX控件打包,在将之转换为</div> </li> <li><a href="/article/2264.htm" title="[宇宙与天文]在太空采矿,在太空建造" target="_blank">[宇宙与天文]在太空采矿,在太空建造</a> <span class="text-muted">comsci</span> <div>     我们在太空进行工业活动...但是不太可能把太空工业产品又运回到地面上进行加工,而一般是在哪里开采,就在哪里加工,太空的微重力环境,可能会使我们的工业产品的制造尺度非常巨大....      地球上制造的最大工业机器是超级油轮和航空母舰,再大些就会遇到困难了,但是在空间船坞中,制造的最大工业机器,可能就没</div> </li> <li><a href="/article/2391.htm" title="ORACLE中CONSTRAINT的四对属性" target="_blank">ORACLE中CONSTRAINT的四对属性</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/CONSTRAINT/1.htm">CONSTRAINT</a> <div>ORACLE中CONSTRAINT的四对属性 summary:在data migrate时,某些表的约束总是困扰着我们,让我们的migratet举步维艰,如何利用约束本身的属性来处理这些问题呢?本文详细介绍了约束的四对属性: Deferrable/not deferrable, Deferred/immediate, enalbe/disable, validate/novalidate,以及如</div> </li> <li><a href="/article/2518.htm" title="Gradle入门教程" target="_blank">Gradle入门教程</a> <span class="text-muted">dengkane</span> <a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a> <div>一、寻找gradle的历程 一开始的时候,我们只有一个工程,所有要用到的jar包都放到工程目录下面,时间长了,工程越来越大,使用到的jar包也越来越多,难以理解jar之间的依赖关系。再后来我们把旧的工程拆分到不同的工程里,靠ide来管理工程之间的依赖关系,各工程下的jar包依赖是杂乱的。一段时间后,我们发现用ide来管理项程很不方便,比如不方便脱离ide自动构建,于是我们写自己的ant脚本。再后</div> </li> <li><a href="/article/2645.htm" title="C语言简单循环示例" target="_blank">C语言简单循环示例</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/c/1.htm">c</a> <div># include <stdio.h> int main(void) { int i; int count = 0; int sum = 0; float avg; for (i=1; i<=100; i++) { if (i%2==0) { count++; sum += i; } } avg</div> </li> <li><a href="/article/2772.htm" title="presentModalViewController 的动画效果" target="_blank">presentModalViewController 的动画效果</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/controller/1.htm">controller</a> <div>系统自带(四种效果): presentModalViewController模态的动画效果设置:     [cpp]  view plain copy   UIViewController *detailViewController = [[UIViewController al</div> </li> <li><a href="/article/2899.htm" title="java 二分查找" target="_blank">java 二分查找</a> <span class="text-muted">shuizhaosi888</span> <a class="tag" taget="_blank" href="/search/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/1.htm">二分查找</a><a class="tag" taget="_blank" href="/search/java%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/1.htm">java二分查找</a> <div>需求:在排好顺序的一串数字中,找到数字T   一般解法:从左到右扫描数据,其运行花费线性时间O(N)。然而这个算法并没有用到该表已经排序的事实。 /** * * @param array * 顺序数组 * @param t * 要查找对象 * @return */ public stati</div> </li> <li><a href="/article/3026.htm" title="Spring Security(07)——缓存UserDetails" target="_blank">Spring Security(07)——缓存UserDetails</a> <span class="text-muted">234390216</span> <a class="tag" taget="_blank" href="/search/ehcache/1.htm">ehcache</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a><a class="tag" taget="_blank" href="/search/Spring+Security/1.htm">Spring Security</a> <div>        Spring Security提供了一个实现了可以缓存UserDetails的UserDetailsService实现类,CachingUserDetailsService。该类的构造接收一个用于真正加载UserDetails的UserDetailsService实现类。当需要加载UserDetails时,其首先会从缓存中获取,如果缓存中没</div> </li> <li><a href="/article/3153.htm" title="Dozer 深层次复制" target="_blank">Dozer 深层次复制</a> <span class="text-muted">jayluns</span> <a class="tag" taget="_blank" href="/search/VO/1.htm">VO</a><a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a><a class="tag" taget="_blank" href="/search/po/1.htm">po</a> <div>最近在做项目上遇到了一些小问题,因为架构在做设计的时候web前段展示用到了vo层,而在后台进行与数据库层操作的时候用到的是Po层。这样在业务层返回vo到控制层,每一次都需要从po-->转化到vo层,用到BeanUtils.copyProperties(source, target)只能复制简单的属性,因为实体类都配置了hibernate那些关联关系,所以它满足不了现在的需求,但后发现还有个很</div> </li> <li><a href="/article/3280.htm" title="CSS规范整理(摘自懒人图库)" target="_blank">CSS规范整理(摘自懒人图库)</a> <span class="text-muted">a409435341</span> <a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/UI/1.htm">UI</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a> <div>   刚没事闲着在网上瞎逛,找了一篇CSS规范整理,粗略看了一下后还蛮有一定的道理,并自问是否有这样的规范,这也是初入前端开发的人一个很好的规范吧。 一、文件规范 1、文件均归档至约定的目录中。 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类。通用的CSS文件,放在如下目录中: 基本样式库 /css/core </div> </li> <li><a href="/article/3407.htm" title="C++动态链接库创建与使用" target="_blank">C++动态链接库创建与使用</a> <span class="text-muted">你不认识的休道人</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/dll/1.htm">dll</a> <div>一、创建动态链接库 1.新建工程test中选择”MFC [dll]”dll类型选择第二项"Regular DLL With MFC shared linked",完成 2.在test.h中添加 extern “C” 返回类型 _declspec(dllexport)函数名(参数列表); 3.在test.cpp中最后写 extern “C” 返回类型 _decls</div> </li> <li><a href="/article/3534.htm" title="Android代码混淆之ProGuard" target="_blank">Android代码混淆之ProGuard</a> <span class="text-muted">rensanning</span> <a class="tag" taget="_blank" href="/search/ProGuard/1.htm">ProGuard</a> <div>Android应用的Java代码,通过反编译apk文件(dex2jar、apktool)很容易得到源代码,所以在release版本的apk中一定要混淆一下一些关键的Java源码。 ProGuard是一个开源的Java代码混淆器(obfuscation)。ADT r8开始它被默认集成到了Android SDK中。 官网: http://proguard.sourceforge.net/</div> </li> <li><a href="/article/3661.htm" title="程序员在编程中遇到的奇葩弱智问题" target="_blank">程序员在编程中遇到的奇葩弱智问题</a> <span class="text-muted">tomcat_oracle</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/ide/1.htm">ide</a> <div>  现在收集一下:         排名不分先后,按照发言顺序来的。   1、Jquery插件一个通用函数一直报错,尤其是很明显是存在的函数,很有可能就是你没有引入jquery。。。或者版本不对 2、调试半天没变化:不在同一个文件中调试。这个很可怕,我们很多时候会备份好几个项目,改完发现改错了。有个群友说的好:   在汤匙</div> </li> <li><a href="/article/3788.htm" title="解决maven-dependency-plugin (goals "copy-dependencies","unpack") is not supported" target="_blank">解决maven-dependency-plugin (goals "copy-dependencies","unpack") is not supported</a> <span class="text-muted">xp9802</span> <a class="tag" taget="_blank" href="/search/dependency/1.htm">dependency</a> <div>解决办法:在plugins之前添加如下pluginManagement,二者前后顺序如下:   [html]  view plain copy   <build>           <pluginManagement</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>