首页
统计
推荐
青柠网盘
Search
1
2.2 导数与微分的求法
532 阅读
2
一、函数 极限与连续性 笔记
384 阅读
3
2.4 微分中值定理
261 阅读
4
8.7.1 线性代数 练习题 答案
220 阅读
5
5.4 多元函数微分学 练习题
214 阅读
黄诗扶
心上诗扶
行程预告
演出信息
入梦记录
物料归档
黄六六喵
目录
日常学习
其他
阿里视觉SDK
时政
高数专业课
高数
电路
模电
数电
实操
笔记
登录
Search
标签搜索
练习题
触发器与时序电路
电子元器件的识别与检测
笔记
电路等效与电路基本定理
答案
三极管电路
组合逻辑电路
DAC与ADC
导数及其应用
一元函数积分学
线性代数
集成运放
微分方程
交流稳态电路的分析及计算
电路分析知识点总结
函数 极限与连续性
电路基本分析方法
交流电路基本概念
二重积分
栋栋
累计撰写
227
篇文章
累计收到
0
条评论
首页
栏目
黄诗扶
心上诗扶
行程预告
演出信息
入梦记录
物料归档
黄六六喵
目录
日常学习
其他
阿里视觉SDK
时政
高数专业课
高数
电路
模电
数电
实操
笔记
页面
统计
推荐
青柠网盘
搜索到
227
篇与
的结果
2025-09-18
衍射极限(Diffraction-limited system)
在光学领域,任何光学仪器或系统,无论是显微镜、望远镜还是相机,由于衍射的物理特性,其分辨率都有一个主要极限。In optics, any optical instrument or system – a microscope, telescope, or camera – has a principal limit to its resolution due to the physics of diffraction. 如果光学仪器的分辨率性能达到了这一极限,则称其为衍射极限。 An optical instrument is said to be diffraction-limited if it has reached this limit of resolution performance. 其他因素也可能影响光学系统的性能,例如透镜缺陷或像差,但这些是由透镜制造或计算中的误差引起的,而衍射极限是理论上完美或理想的光学系统所能达到的最大分辨率。Other factors may affect an optical system's performance, such as lens imperfections or aberrations, but these are caused by errors in the manufacture or calculation of a lens, whereas the diffraction limit is the maximum resolution possible for a theoretically perfect, or ideal, optical system.仪器的 衍射极限角分辨率 (以弧度为单位)与 被观测光的波长 成正比,与 物镜入射孔径 成反比。 The diffraction-limited angular resolution , in radians, of an instrument is proportional to the wavelength of the light being observed, and inversely proportional to the diameter of its objective's entrance aperture . 对于具有圆形孔径的望远镜,图像中受衍射极限影响的 最小特征的大小 等于艾里斑(Airy disk)的大小。 For telescopes with circular apertures, the size of the smallest feature in an image that is diffraction limited is the size of the Airy disk.随着望远镜头孔径的减小,衍射会成比例增加。在小孔径(例如f/22)下,大多数现代镜头仅受衍射限制,而不会受到像差或其他结构缺陷的限制。As one decreases the size of the aperture of a telescopic lens, diffraction proportionately increases.As one decreases the size of the aperture of a telescopic lens, diffraction proportionately increases.对于显微仪器,衍射极限空间分辨率与光波长成正比,并且与物镜或物体照明源的 数值孔径(以较小者为准)。For microscopic instruments, the diffraction-limited spatial resolution is proportional to the light wavelength, and to the numerical aperture of either the objective or the object illumination source, whichever is smaller.在天文学中,衍射极限观测是指在所用仪器尺寸范围内达到理论理想物镜分辨率的观测。In astronomy, a diffraction-limited observation is one that achieves the resolution of a theoretically ideal objective in the size of instrument used. 然而,由于大气效应,大多数地球观测的视场都有限。However, most observations from Earth are seeing-limited due to atmospheric effects.由于光线穿过数公里湍流大气时产生的畸变,地球上的光学望远镜的分辨率远低于衍射极限。Optical telescopes on the Earth work at a much lower resolution than the diffraction limit because of the distortion introduced by the passage of light through several kilometres of turbulent atmosphere. 先进的天文台已经开始使用自适应光学技术,从而提高了暗淡目标的图像分辨率,但使用自适应光学技术仍然难以达到衍射极限。Advanced observatories have started using adaptive optics technology, resulting in greater image resolution for faint targets, but it is still difficult to reach the diffraction limit using adaptive optics.射电望远镜通常受到衍射极限的影响,因为它们使用的波长(从毫米到米)非常长,大气畸变可以忽略不计。Radio telescopes are frequently diffraction-limited, because the wavelengths they use (from millimeters to meters) are so long that the atmospheric distortion is negligible. 太空望远镜(例如哈勃望远镜或许多非光学望远镜)如果其设计没有光学像差,则始终工作在衍射极限。Space-based telescopes (such as Hubble, or a number of non-optical telescopes) always work at their diffraction limit, if their design is free of optical aberration.具有近乎理想光束传播特性的激光器产生的光束可以被描述为衍射极限光束。The beam from a laser with near-ideal beam propagation properties may be described as being diffraction-limited.衍射极限激光束穿过衍射极限光学元件后,仍将保持衍射极限,其空间或角度范围基本等于光学元件在激光波长下的分辨率。A diffraction-limited laser beam, passed through diffraction-limited optics, will remain diffraction-limited, and will have a spatial or angular extent essentially equal to the resolution of the optics at the wavelength of the laser.
2025年09月18日
6 阅读
0 评论
0 点赞
2025-09-12
「入梦」系列周边第一款-正肩短袖T恤
暂无简介
2025年09月12日
0 阅读
0 评论
0 点赞
2025-09-07
小米R4A V2刷入openwrt 实现校园网自动认证
一、路由器刷入openwrt系统{callout color="#ff0f0f"}区分v1与v2版本小米路由器4A千兆版分为了v1和v2打开小米路由器后台,进入系统信息查看当前固件版本新购买的路由器版本号可能为 2.30.28 ,如果你是23年前购买的老机型大概率是V1版本。 2.30.为v2,2.28.为v1 v1版本与v2版本是有区别的,不能刷相同的固件,因此这里我们以v2作为教程版本。{/callout}1.开Telnet双击运行 1.V2版开Telnet.bat程序 第一个为路由器ip第二个为当前设备的ip密码为路由器管理员密码2.连接路由器,备份固件{alert type="warning"}这步很重要!如果没成功备份固件后续变砖就无法救了!{/alert}直接打开刷机工具包里的putty工具双击R4A进入即可账户密码均为root备份编程器固件cat /proc/mtd&&dd if=/dev/mtd0 of=/tmp/ALL_backup.bin&&dd if=/dev/mtd4 of=/tmp/eeprom.bin使用FlashFXP 下载备份固件保存tmp目录里的 ALL_backup.bin 和 eeprom.bin 到电脑.同时将breed.bin上传到tmp目录{alert type="warning"}注意看看文件大小!不要没有传成功{/alert}3.刷入breed验证breed.bin的MD5数值md5sum /tmp/breed.binMD5值应当为 24e62762809c15ba3872e610a37451a3 使用命令mtd write /tmp/breed.bin Bootloader刷入breed固件使用命令 reboot 重启路由器重启完成后浏览器192.168.1.1进入管理界面{callout color="#f0ad4e"}以后要进入breed的方法是路由器断电 按住复位键不放 路由器通电 等5到10秒钟 松开复位键 浏览器输入192.168.1.1{/callout}4.刷入openwrt点击 固件更新-常规固件 选择好固件(.bin文件)和EEPROM(之前备份的eeprom.bin) 点击上传即可确认一遍是否正确 点击更新进度条跑完即可等待路由器重启啦!如果路由器一直闪黄灯进入安全模式,可以拔掉电源硬重启一次5.进入系统192.168.31.1进入openwrt管理界面二、无网线接口配置方法网络->无线->扫描选择需要连接的网络默认提交确认为客户端模式,且网络接口为之前创建的三、获取认证接口 构建认证请求通过抓包测试,可知登录 注销等接口1.登录接口http://210.28.39.251:801/eportal/?user_account=<用户名>&wlan_user_ip=<当前设备IP>&login_method=1&user_password=<密码>&c=Portal&a=login Host: 210.28.39.251:801 Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0 Referer: http://210.28.39.251/ Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.62.注销接口http://210.28.39.251:801/eportal/?c=Portal&a=logout&ac_logout=0®ister_mode=1&wlan_user_ip=<当前设备IP>&user_account=drcom Host: 210.28.39.251:801 Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0 Accept: */* Referer: http://210.28.39.251/ Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.63.构造认证请求文件根据个人需求编写auto_login.sh脚本{collapse}{collapse-item label="auto_login.sh" open}#!/bin/sh # 校园网认证脚本 # 首先获取当前WAN口IP,然后使用该IP进行认证 # 设置日志文件路径 LOG_FILE="/tmp/auto_login.log" # 获取WWAN接口的IP地址 # 假设你的无线客户端接口是wwan(根据第一步配置) CURRENT_IP=$(ifconfig wwan 2>/dev/null | awk '/inet addr/{print substr($2,6)}') USERNAME="" PASSWORD="" # 如果没有获取到IP,尝试使用其他方法 if [ -z "$CURRENT_IP" ]; then CURRENT_IP=$(ubus call network.interface.wwan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address') fi # 如果仍然没有IP,记录错误并退出 if [ -z "$CURRENT_IP" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误: 无法获取WAN口IP地址" >> $LOG_FILE exit 1 fi echo "[$(date +'%Y-%m-%d %H:%M:%S')] 获取到IP: $CURRENT_IP" >> $LOG_FILE # 构造认证URL AUTH_URL="http://210.28.39.251:801/eportal/?user_account=${USERNAME}&wlan_user_ip=${CURRENT_IP}&login_method=1&user_password=${PASSWORD}&c=Portal&a=login" # 发送第一次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第一次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第一次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证响应: $RESPONSE" >> $LOG_FILE # 解析第一次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"'; then if echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 已经在线,无需重复认证" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证失败,等待2秒后重试..." >> $LOG_FILE sleep 2 # 发送第二次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第二次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第二次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证响应: $RESPONSE" >> $LOG_FILE # 解析第二次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"' && echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次尝试时已经在线" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证失败: $RESPONSE" >> $LOG_FILE exit 1 fi fi else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 未知响应,等待2秒后重试..." >> $LOG_FILE sleep 2 # 发送第二次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第二次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第二次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证响应: $RESPONSE" >> $LOG_FILE # 解析第二次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"' && echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次尝试时已经在线" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证失败: $RESPONSE" >> $LOG_FILE exit 1 fi fi{/collapse-item}{collapse-item label="9月11更新auto_login.sh"}#!/bin/sh # 校园网认证脚本 # 首先获取当前WAN口IP,然后使用该IP进行认证 # 设置日志文件路径 LOG_FILE="/tmp/auto_login.log" # 获取WWAN接口的IP地址 # 假设你的无线客户端接口是wwan(根据第一步配置) CURRENT_IP=$(ifconfig wwan 2>/dev/null | awk '/inet addr/{print substr($2,6)}') USERNAME="" PASSWORD="" # 如果没有获取到IP,尝试使用其他方法 if [ -z "$CURRENT_IP" ]; then CURRENT_IP=$(ubus call network.interface.wwan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address') fi # 如果仍然没有IP,记录错误并退出 if [ -z "$CURRENT_IP" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误: 无法获取WAN口IP地址" >> $LOG_FILE exit 1 fi echo "[$(date +'%Y-%m-%d %H:%M:%S')] 获取到IP: $CURRENT_IP" >> $LOG_FILE # 构造认证URL AUTH_URL="http://210.28.39.251:801/eportal/?user_account=${USERNAME}&wlan_user_ip=${CURRENT_IP}&login_method=1&user_password=${PASSWORD}&c=Portal&a=login" # 发送第一次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第一次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第一次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证响应: $RESPONSE" >> $LOG_FILE # 解析第一次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"'; then if echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 已经在线,无需重复认证" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证失败,等待5秒后重试..." >> $LOG_FILE sleep 5 # 发送第二次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第二次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第二次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证响应: $RESPONSE" >> $LOG_FILE # 解析第二次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"' && echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次尝试时已经在线" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证失败: $RESPONSE;当前IP为:$CURRENT_IP" >> $LOG_FILE exit 1 fi fi else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 未知响应,等待5秒后重试...;当前IP为:$CURRENT_IP;URL为:$AUTH_URL" >> $LOG_FILE sleep 5 # 发送第二次认证请求 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第二次认证请求..." >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$AUTH_URL" \ -H "Host: 210.28.39.251:801" \ -H "Connection: keep-alive" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" \ -H "Referer: http://210.28.39.251/" \ -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6") # 记录第二次响应 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证响应: $RESPONSE" >> $LOG_FILE # 解析第二次响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证成功" >> $LOG_FILE exit 0 elif echo "$RESPONSE" | grep -q '"result":"0"' && echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次尝试时已经在线" >> $LOG_FILE exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第二次认证失败: $RESPONSE;当前IP为:$CURRENT_IP" >> $LOG_FILE exit 1 fi fi{/collapse-item}{collapse-item label="9月14更新auto_login.shIP地址变化导致,构建的URL不正确,更新每次认证前,重新获取一次IP"}#!/bin/sh # 校园网认证脚本 # 首先获取当前WAN口IP,然后使用该IP进行认证 USER_ACCOUNT="" USER_PASSWORD="" AUTH_SERVER="" # HTTP请求头部定义 HOST_HEADER="" REFERER_HEADER="" USER_AGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0" CONNECTION="keep-alive" ACCEPT_LANGUAGE="zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6" # 设置日志文件路径 LOG_FILE="/tmp/auto_login.log" # 函数:获取当前WWAN接口的IP地址 get_current_ip() { # 尝试多种方法获取IP地址 local ip=$(ifconfig wwan 2>/dev/null | awk '/inet addr/{print substr($2,6)}') # 如果没有获取到IP,尝试使用其他方法 if [ -z "$ip" ]; then ip=$(ubus call network.interface.wwan status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address') fi # 如果依然获取不到,尝试使用ip命令 if [ -z "$ip" ]; then ip=$(ip -4 addr show dev wwan 2>/dev/null | grep -oE 'inet [0-9.]+' | cut -d' ' -f2) fi # 如果仍然没有IP,记录错误 if [ -z "$ip" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误: 无法获取WAN口IP地址" >> $LOG_FILE echo "" # 返回空字符串 else echo "$ip" fi } # 函数:发送认证请求 send_auth_request() { local ip=$1 local attempt=$2 local auth_url="http://${AUTH_SERVER}/eportal/?user_account=${USER_ACCOUNT}&wlan_user_ip=${ip}&login_method=1&user_password=${USER_PASSWORD}&c=Portal&a=login" echo "[$(date +'%Y-%m-%d %H:%M:%S')] 发送第${attempt}次认证请求..." >> $LOG_FILE # echo "[$(date +'%Y-%m-%d %H:%M:%S')] 认证URL: $auth_url" >> $LOG_FILE RESPONSE=$(curl -s -X GET \ "$auth_url" \ -H "Host: $HOST_HEADER" \ -H "Connection: $CONNECTION" \ -H "User-Agent: $USER_AGENT" \ -H "Referer: $REFERER_HEADER" \ -H "Accept-Language: $ACCEPT_LANGUAGE") echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第${attempt}次认证响应: $RESPONSE" >> $LOG_FILE # 解析响应结果 if echo "$RESPONSE" | grep -q '"result":"1"'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第${attempt}次认证成功" >> $LOG_FILE return 0 elif echo "$RESPONSE" | grep -q '"result":"0"' && echo "$RESPONSE" | grep -q '"ret_code":2'; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第${attempt}次尝试时已经在线,无需重复认证" >> $LOG_FILE return 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第${attempt}次认证失败;响应:$RESPONSE;认证URL:$auth_url" >> $LOG_FILE return 1 fi } # 获取当前IP CURRENT_IP=$(get_current_ip) if [ -z "$CURRENT_IP" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误: 无法获取WAN口IP地址,退出脚本" >> $LOG_FILE exit 1 fi echo "[$(date +'%Y-%m-%d %H:%M:%S')] 获取到IP: $CURRENT_IP" >> $LOG_FILE # 第一次认证尝试 if send_auth_request "$CURRENT_IP" "一"; then exit 0 fi # 第一次尝试失败,等待5秒后重试 echo "[$(date +'%Y-%m-%d %H:%M:%S')] 第一次认证失败,等待5秒后重试..." >> $LOG_FILE sleep 5 # 第二次尝试前重新获取IP NEW_IP=$(get_current_ip) if [ -z "$NEW_IP" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 错误: 重试时无法获取WAN口IP地址,退出脚本" >> $LOG_FILE exit 1 fi # 检查IP是否变化 if [ "$NEW_IP" != "$CURRENT_IP" ]; then echo "[$(date +'%Y-%m-%d %H:%M:%S')] 检测到IP地址变化:${CURRENT_IP} -> ${NEW_IP}" >> $LOG_FILE CURRENT_IP="$NEW_IP" fi # 第二次认证尝试 if send_auth_request "$CURRENT_IP" "二"; then exit 0 else echo "[$(date +'%Y-%m-%d %H:%M:%S')] 认证最终失败; 当前IP为: $CURRENT_IP" >> $LOG_FILE exit 1 fi{/collapse-item}{/collapse}4.上传到路由器使用putty软件连接到路由器后面使用vim进行操作1.创建auto_login.sh文件vi /etc/auto_login.sh2.在vi编辑器下,按 i 进入编辑模式,按 Shift+Insert 将准备好的脚本粘贴上去,然后按 esc 退出编辑模式,然后输入 :wq 并回车即可保存。若输入错误,在退出编辑模式后,输入 :q! 不保存退出,如何再重新打开编辑 若要全部删除:按 esc 键后,先按 gg (到达顶部),然后 dG 即可。3.设置权限chmod +x /etc/auto_login.sh4.手动运行一次测试一下/etc/auto_login.sh5.查看日志记录cat /tmp/auto_login.log6.设置计划任务 每30分钟运行一次*/30 * * * * /etc/auto_login.sh5.IP监测1.创建 check_ip_change.sh 文件vi /etc/check_ip_change.sh{collapse}{collapse-item label="check_ip_change.sh 文件" open}#!/bin/sh # 接口名称 INTERFACE="wwan" # 用于存储上次IP的文件 IP_FILE="/tmp/last_ip_${INTERFACE}.txt" # 日志文件 LOG_FILE="/tmp/auto_login.log" # 循环次数 LOOP_COUNT=29 # 循环间隔(秒) LOOP_INTERVAL=60 # 获取当前IP地址 get_current_ip() { # 尝试多种方法获取IP地址 local ip="" ip=$(ifconfig ${INTERFACE} 2>/dev/null | awk '/inet addr/{print substr($2,6)}') # 如果没有获取到IP,尝试使用其他方法 if [ -z "$ip" ]; then ip=$(ubus call network.interface.${INTERFACE} status 2>/dev/null | jsonfilter -e '@["ipv4-address"][0].address') fi # 如果依然获取不到,尝试使用ip命令 if [ -z "$ip" ]; then ip=$(ip -4 addr show dev ${INTERFACE} 2>/dev/null | grep -oE 'inet [0-9.]+' | cut -d' ' -f2) fi echo "$ip" } # 记录日志函数 log() { echo "$(date '+%Y-%m-%d %H:%M:%S') check_ip_change.sh-> $1" >> ${LOG_FILE} # logger -t ip-change-detector "$1" } # 主循环函数 main_loop() { for i in $(seq 1 $LOOP_COUNT); do # log "循环第 $i/$LOOP_COUNT 次" # 获取当前IP current_ip=$(get_current_ip) # 如果无法获取当前IP,记录错误但继续循环 if [ -z "${current_ip}" ]; then log "警告: 无法获取接口 ${INTERFACE} 的IP地址" sleep $LOOP_INTERVAL continue fi # log "当前检测到IP: ${current_ip}" # 检查是否存在存储的上次IP if [ -f "${IP_FILE}" ]; then last_ip=$(cat ${IP_FILE}) log "上次记录的IP: ${last_ip}" # 比较IP是否变化 if [ "${current_ip}" != "${last_ip}" ]; then log "检测到IP变化,当前检测到IP: ${current_ip},上次记录的IP: ${last_ip},执行认证脚本..." # 执行认证脚本 if [ -x "/etc/auto_login.sh" ]; then /etc/auto_login.sh >> ${LOG_FILE} 2>&1 auth_result=$? if [ ${auth_result} -eq 0 ]; then log "认证脚本执行成功" else log "认证脚本执行失败,返回码: ${auth_result}" fi else log "错误: 认证脚本 /etc/auto_login.sh 不存在或不可执行" fi # 更新存储的IP echo "${current_ip}" > ${IP_FILE} log "已更新存储的IP为: ${current_ip}" fi else # 首次运行,创建IP记录文件 echo "${current_ip}" > ${IP_FILE} log "首次运行,记录IP: ${current_ip}" fi # 等待下一次循环 if [ $i -lt $LOOP_COUNT ]; then sleep $LOOP_INTERVAL fi done } # 执行主循环 main_loop log "完成 ${LOOP_COUNT} 次循环检测,脚本退出" {/collapse-item}{/collapse}2.设置权限chmod +x /etc/check_ip_change.sh3.设置计划任务 每分钟运行一次* * * * * /etc/check_ip_change.sh # 丢弃所有输出 不保留任何日志 * * * * * /etc/check_ip_change.sh >/dev/null 2>&16.配置web设置界面1.创建用于读写的脚本vi /www/cgi-bin/read_file.cgi vi /www/cgi-bin/write_file.cgiread_file.cgi文件 {collapse}{collapse-item label="read_file.cgi" open}#!/bin/sh echo "Content-type: text/plain" echo "" # 获取查询字符串中的file参数 FILE=$(echo "$QUERY_STRING" | sed -n 's/^.*file=\([^&]*\).*$/\1/p' | sed "s/%20/ /g") # 将相对路径转换为绝对路径 case "$FILE" in ./etc/auto_login.sh) ABS_PATH="/etc/auto_login.sh" ;; ./tmp/auto_login.log) ABS_PATH="/tmp/auto_login.log" ;; *) echo "错误: 无权访问该文件" exit 1 ;; esac # 改进的安全检查:只防止包含../的路径遍历,允许单个. if echo "$FILE" | grep -q "\.\./"; then echo "错误: 无效的文件路径(包含路径遍历)" exit 1 fi # 检查文件是否存在 if [ ! -f "$ABS_PATH" ]; then echo "错误: 文件不存在: $ABS_PATH" exit 1 fi # 读取文件内容 cat "$ABS_PATH" {/collapse-item}{/collapse}write_file.cgi文件 {collapse}{collapse-item label="write_file.cgi" open}#!/bin/sh echo "Content-type: text/plain" echo "" # 读取POST数据 read -r POST_DATA # 解析POST数据,获取file和content参数 FILE_PARAM=$(echo "$POST_DATA" | sed 's/&.*//' | sed 's/file=//') CONTENT_PARAM=$(echo "$POST_DATA" | sed 's/.*&//' | sed 's/content=//') # 对URL编码进行解码 FILE=$(printf "%b" "$(echo "$FILE_PARAM" | sed 's/+/ /g; s/%/\\x/g')") CONTENT=$(printf "%b" "$(echo "$CONTENT_PARAM" | sed 's/+/ /g; s/%/\\x/g')") # 将相对路径转换为绝对路径 case "$FILE" in "./etc/auto_login.sh") ABS_PATH="/etc/auto_login.sh" ;; *) echo "错误: 只能保存到auto_login.sh文件" exit 1 ;; esac # 安全检查:防止路径遍历攻击 if echo "$ABS_PATH" | grep -q "\.\."; then echo "错误: 无效的文件路径" exit 1 fi # 只允许写入特定文件 if [ "$ABS_PATH" = "/etc/auto_login.sh" ]; then # 检查目录是否存在且可写 if [ ! -w "$(dirname "$ABS_PATH")" ]; then echo "错误: 目录不可写: $(dirname "$ABS_PATH")" exit 1 fi # 写入文件 echo "$CONTENT" > "$ABS_PATH" # 检查是否成功写入 if [ $? -eq 0 ]; then echo "文件保存成功" else echo "错误: 文件保存失败" exit 1 fi else echo "错误: 只能保存到auto_login.sh文件" exit 1 fi{/collapse-item}{collapse-item label="9月11更新write_file.cgi"}#!/bin/sh echo "Content-type: text/plain" echo "" # 读取POST数据 read -r POST_DATA # 解析POST数据,获取file和content参数 FILE_PARAM=$(echo "$POST_DATA" | sed 's/&.*//' | sed 's/file=//') CONTENT_PARAM=$(echo "$POST_DATA" | sed 's/.*&//' | sed 's/content=//') # 对URL编码进行解码 FILE=$(printf "%b" "$(echo "$FILE_PARAM" | sed 's/+/ /g; s/%/\\x/g')") CONTENT=$(printf "%b" "$(echo "$CONTENT_PARAM" | sed 's/+/ /g; s/%/\\x/g')") # 将相对路径转换为绝对路径 case "$FILE" in "./etc/auto_login.sh") ABS_PATH="/etc/auto_login.sh" ;; *) echo "错误: 只能保存到auto_login.sh文件" exit 1 ;; esac # 安全检查:防止路径遍历攻击 if echo "$ABS_PATH" | grep -q "\.\."; then echo "错误: 无效的文件路径" exit 1 fi # 只允许写入特定文件 if [ "$ABS_PATH" = "/etc/auto_login.sh" ]; then # 检查目录是否存在且可写 if [ ! -w "$(dirname "$ABS_PATH")" ]; then echo "错误: 目录不可写: $(dirname "$ABS_PATH")" exit 1 fi # 写入文件 echo "$CONTENT" > "$ABS_PATH" # 检查是否成功写入 if [ $? -eq 0 ]; then echo "文件保存成功" #2025.9.11添加 保存后自动运行一次 # 添加执行权限 chmod +x "$ABS_PATH" # 延迟1秒后执行 # sleep 1 # 执行脚本并捕获输出 OUTPUT=$($ABS_PATH 2>&1) echo "脚本执行结果: $OUTPUT" else echo "错误: 文件保存失败" exit 1 fi else echo "错误: 只能保存到auto_login.sh文件" exit 1 fi{/collapse-item}{/collapse}2.创建网页文件先创建目录和文件mkdir -p www/webconfig/ vi /www/webconfig/index.htmlindex.html文件 {collapse}{collapse-item label="index.html" open}<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>OpenWrt 自动登录配置</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background-color: #f5f5f5; padding: 20px; max-width: 1200px; margin: 0 auto; } header { background-color: #2c3e50; color: white; padding: 1rem; border-radius: 5px; margin-bottom: 20px; text-align: center; } h1 { font-size: 1.8rem; margin-bottom: 0.5rem; } .description { font-size: 1rem; opacity: 0.9; } .container { display: flex; flex-wrap: wrap; gap: 20px; } .panel { flex: 1; min-width: 300px; background: white; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); padding: 20px; } .panel h2 { margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #eaeaea; color: #2c3e50; } .editor { width: 100%; min-height: 300px; font-family: monospace; padding: 10px; border: 1px solid #ddd; border-radius: 4px; resize: vertical; } .log-view { width: 100%; min-height: 300px; max-height: 500px; overflow-y: auto; font-family: monospace; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background-color: #f8f8f8; white-space: pre-wrap; } .buttons { margin-top: 15px; display: flex; gap: 10px; } button { padding: 8px 16px; background-color: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 500; transition: background-color 0.2s; } button:hover { background-color: #2980b9; } button.save { background-color: #27ae60; } button.save:hover { background-color: #219653; } button.refresh { background-color: #95a5a6; } button.refresh:hover { background-color: #7f8c8d; } .status { margin-top: 10px; padding: 8px; border-radius: 4px; display: none; } .status.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; display: block; } .status.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; display: block; } .loading { color: #7f8c8d; font-style: italic; } @media (max-width: 768px) { .container { flex-direction: column; } } </style> </head> <body> <header> <h1>OpenWrt 自动登录配置</h1> <p class="description">编辑自动登录脚本并查看运行日志</p> </header> <div class="container"> <div class="panel"> <h2>自动登录脚本 (./etc/auto_login.sh)</h2> <textarea id="editor" class="editor" placeholder="加载中..."></textarea> <div class="buttons"> <button id="saveBtn" class="save">保存更改</button> <button id="reloadBtn" class="refresh">重新加载</button> </div> <div id="editorStatus" class="status"></div> </div> <div class="panel"> <h2>运行日志 (./tmp/auto_login.log)</h2> <pre id="logView" class="log-view">加载日志内容...</pre> <div class="buttons"> <button id="refreshLogBtn" class="refresh">刷新日志</button> </div> <div id="logStatus" class="status"></div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const editor = document.getElementById('editor'); const logView = document.getElementById('logView'); const saveBtn = document.getElementById('saveBtn'); const reloadBtn = document.getElementById('reloadBtn'); const refreshLogBtn = document.getElementById('refreshLogBtn'); const editorStatus = document.getElementById('editorStatus'); const logStatus = document.getElementById('logStatus'); // 加载脚本内容 function loadScript() { editor.classList.add('loading'); editor.value = '加载中...'; fetch('/cgi-bin/read_file.cgi?file=./etc/auto_login.sh') .then(response => { if (!response.ok) { throw new Error('无法读取文件'); } return response.text(); }) .then(data => { editor.value = data; editor.classList.remove('loading'); showStatus(editorStatus, '脚本加载成功', 'success'); }) .catch(error => { editor.value = ''; showStatus(editorStatus, '错误: ' + error.message, 'error'); editor.classList.remove('loading'); }); } // 加载日志内容 function loadLog() { logView.textContent = '加载中...'; logView.classList.add('loading'); fetch('/cgi-bin/read_file.cgi?file=./tmp/auto_login.log') .then(response => { if (!response.ok) { throw new Error('无法读取日志文件'); } return response.text(); }) .then(data => { logView.textContent = data || '日志文件为空'; logView.classList.remove('loading'); showStatus(logStatus, '日志加载成功', 'success'); }) .catch(error => { logView.textContent = '加载失败: ' + error.message; showStatus(logStatus, '错误: ' + error.message, 'error'); logView.classList.remove('loading'); }); } // 保存脚本内容 function saveScript() { const content = editor.value; fetch('/cgi-bin/write_file.cgi', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `file=./etc/auto_login.sh&content=${encodeURIComponent(content)}` }) .then(response => { if (!response.ok) { throw new Error('保存失败'); } return response.text(); }) .then(data => { showStatus(editorStatus, '保存成功', 'success'); }) .catch(error => { showStatus(editorStatus, '错误: ' + error.message, 'error'); }); } // 显示状态消息 function showStatus(element, message, type) { element.textContent = message; element.className = 'status ' + type; // 3秒后隐藏状态消息 setTimeout(() => { element.className = 'status'; element.textContent = ''; }, 3000); } // 绑定按钮事件 saveBtn.addEventListener('click', saveScript); reloadBtn.addEventListener('click', loadScript); refreshLogBtn.addEventListener('click', loadLog); // 初始加载内容 loadScript(); loadLog(); }); </script> </body> </html>{/collapse-item}{collapse-item label="9月11更新index.html"}<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>OpenWrt 自动登录配置</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background-color: #f5f5f5; padding: 20px; max-width: 1200px; margin: 0 auto; } header { background-color: #2c3e50; color: white; padding: 1rem; border-radius: 5px; margin-bottom: 20px; text-align: center; } h1 { font-size: 1.8rem; margin-bottom: 0.5rem; } .description { font-size: 1rem; opacity: 0.9; } .container { display: flex; flex-wrap: wrap; gap: 20px; } .panel { flex: 1; min-width: 300px; background: white; border-radius: 5px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); padding: 20px; } .panel h2 { margin-bottom: 15px; padding-bottom: 10px; border-bottom: 2px solid #eaeaea; color: #2c3e50; } .editor { width: 100%; min-height: 300px; font-family: monospace; padding: 10px; border: 1px solid #ddd; border-radius: 4px; resize: vertical; } .log-view { width: 100%; min-height: 300px; max-height: 500px; overflow-y: auto; font-family: monospace; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background-color: #f8f8f8; white-space: pre-wrap; } .buttons { margin-top: 15px; display: flex; gap: 10px; flex-wrap: wrap; } button { padding: 8px 16px; background-color: #3498db; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 500; transition: background-color 0.2s; } button:hover { background-color: #2980b9; } button.save { background-color: #27ae60; } button.save:hover { background-color: #219653; } button.refresh { background-color: #95a5a6; } button.refresh:hover { background-color: #7f8c8d; } button.download { background-color: #9b59b6; } button.download:hover { background-color: #8e44ad; } .status { margin-top: 10px; padding: 8px; border-radius: 4px; display: none; } .status.success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; display: block; } .status.error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; display: block; } .loading { color: #7f8c8d; font-style: italic; } @media (max-width: 768px) { .container { flex-direction: column; } .buttons { flex-direction: column; } button { width: 100%; } } </style> </head> <body> <header> <h1>OpenWrt 自动登录配置</h1> <p class="description">编辑自动登录脚本并查看运行日志</p> </header> <div class="container"> <div class="panel"> <h2>自动登录脚本 (./etc/auto_login.sh)</h2> <textarea id="editor" class="editor" placeholder="加载中..."></textarea> <div class="buttons"> <button id="saveBtn" class="save">保存更改</button> <button id="reloadBtn" class="refresh">重新加载</button> </div> <div id="editorStatus" class="status"></div> </div> <div class="panel"> <h2>运行日志 (./tmp/auto_login.log)</h2> <pre id="logView" class="log-view">加载日志内容...</pre> <div class="buttons"> <button id="refreshLogBtn" class="refresh">刷新日志</button> <button id="downloadLogBtn" class="download">下载日志</button> </div> <div id="logStatus" class="status"></div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const editor = document.getElementById('editor'); const logView = document.getElementById('logView'); const saveBtn = document.getElementById('saveBtn'); const reloadBtn = document.getElementById('reloadBtn'); const refreshLogBtn = document.getElementById('refreshLogBtn'); const downloadLogBtn = document.getElementById('downloadLogBtn'); const editorStatus = document.getElementById('editorStatus'); const logStatus = document.getElementById('logStatus'); // 加载脚本内容 function loadScript() { editor.classList.add('loading'); editor.value = '加载中...'; fetch('/cgi-bin/read_file.cgi?file=./etc/auto_login.sh') .then(response => { if (!response.ok) { throw new Error('无法读取文件'); } return response.text(); }) .then(data => { editor.value = data; editor.classList.remove('loading'); showStatus(editorStatus, '脚本加载成功', 'success'); }) .catch(error => { editor.value = ''; showStatus(editorStatus, '错误: ' + error.message, 'error'); editor.classList.remove('loading'); }); } // 加载日志内容 function loadLog() { logView.textContent = '加载中...'; logView.classList.add('loading'); fetch('/cgi-bin/read_file.cgi?file=./tmp/auto_login.log') .then(response => { if (!response.ok) { throw new Error('无法读取日志文件'); } return response.text(); }) .then(data => { logView.textContent = data || '日志文件为空'; logView.classList.remove('loading'); showStatus(logStatus, '日志加载成功', 'success'); }) .catch(error => { logView.textContent = '加载失败: ' + error.message; showStatus(logStatus, '错误: ' + error.message, 'error'); logView.classList.remove('loading'); }); } // 保存脚本内容 function saveScript() { const content = editor.value; fetch('/cgi-bin/write_file.cgi', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `file=./etc/auto_login.sh&content=${encodeURIComponent(content)}` }) .then(response => { if (!response.ok) { throw new Error('保存失败'); } return response.text(); }) .then(data => { showStatus(editorStatus, '保存成功', 'success'); }) .catch(error => { showStatus(editorStatus, '错误: ' + error.message, 'error'); }); } // 下载日志功能 function downloadLog() { const logContent = logView.textContent; if (!logContent || logContent === '加载中...' || logContent === '加载日志内容...') { showStatus(logStatus, '没有可下载的日志内容', 'error'); return; } try { // 创建Blob对象 const blob = new Blob([logContent], { type: 'text/plain' }); const url = URL.createObjectURL(blob); // 创建下载链接 const a = document.createElement('a'); a.href = url; a.download = 'auto_login.log'; document.body.appendChild(a); a.click(); // 清理 setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); showStatus(logStatus, '日志下载成功', 'success'); }, 100); } catch (error) { showStatus(logStatus, '下载失败: ' + error.message, 'error'); } } // 显示状态消息 function showStatus(element, message, type) { element.textContent = message; element.className = 'status ' + type; // 3秒后隐藏状态消息 setTimeout(() => { element.className = 'status'; element.textContent = ''; }, 3000); } // 绑定按钮事件 saveBtn.addEventListener('click', saveScript); reloadBtn.addEventListener('click', loadScript); refreshLogBtn.addEventListener('click', loadLog); downloadLogBtn.addEventListener('click', downloadLog); // 初始加载内容 loadScript(); loadLog(); }); </script> </body> </html>{/collapse-item}{/collapse}3.设置权限chmod +x /www/cgi-bin/read_file.cgi /www/cgi-bin/write_file.cgi4.管理地址管理地址 所有工具和包隐藏内容,请前往内页查看详情
2025年09月07日
25 阅读
0 评论
0 点赞
2025-09-05
一起吹吹夏日风,六六带来一条开票提醒~ 10月4日武汉站预售:9月5日18:00
一起吹吹夏日风,六六带来一条开票提醒~10月4日武汉站预售:9月5日18:00
2025年09月05日
0 阅读
0 评论
0 点赞
2025-09-01
「栗子熟时,来信展秋」
「栗子熟时,来信展秋」
2025年09月01日
0 阅读
0 评论
0 点赞
2025-08-31
后台演员花絮分享,可爱的大家我们武汉见~
后台演员花絮分享,可爱的大家我们武汉见~
2025年08月31日
1 阅读
0 评论
0 点赞
2025-02-15
人脸识别SDK
人脸搜索 创建人脸数据库 查询人脸数据库列表 添加人脸样本 查询人脸样本 查询人脸样本列表 更新人脸样本 添加人脸数据 批量添加人脸数据 删除人脸 删除人脸样本 删除数据库 人脸活体检测
2025年02月15日
11 阅读
0 评论
0 点赞
2025-02-15
人脸活体检测
功能描述人脸活体检测能力可以检测图像中的人脸是否为来自认证设备端的近距离裸拍活体人脸对象,可广泛应用在人脸实时采集场景,满足人脸注册认证的真实性和安全性要求。活体判断的前置条件是图像中有人脸。 能力范围来看: 1. 认证设备端是指借助近距离裸拍活体正面人脸用于认证、通行等服务场景的含RGB摄像头的硬件设备,常见的认证设备端有手机、门禁机、考勤机、PC等智能终端认证设备。 2. 裸拍活体正面人脸是指真人未经重度PS、风格化、人工合成等后处理的含正面人脸(非模糊、遮挡、大角度的正面人脸)的照片。常见的非真人有纸张人脸、电子屏人脸等;常见经过重度PS后处理的照片有摆拍街景照、摆拍人物风景照、摆拍证件照等;常见的其他后处理及生成照片有动漫人脸、绘画人脸等。应用场景系统人脸登录防攻击:通过检测上传的图像是否为真人实拍,而非攻击及PS等后处理照片,以防止攻击者登录系统带来安全风险。门禁闸机刷脸通行:面向人脸注册和认证环节设备端实时的活体检测,实现注册与认证过程中的真人校验,防止非法分子盗用、伪造他人身份打卡通行。智慧酒店自助入住:在酒店前台自助办理入住场景中,运用活体检测技术实现无人监管场景下,住客非活体攻击(纸张人脸、电子屏人脸)的高效率拦截。金融远程身份认证:面向投资理财、基金交易、保险理赔等金融业务的活体检测需求,高效率实现对翻拍、PS图片、打印图片、高仿模具等攻击的拦截,确保用户身份真实。特色优势基于图片中人像目标的高维度特征(风格化、摩尔纹、成像畸形等),判断目标对象是否为活体,有效防止屏幕二次翻拍等作弊攻击,支持单张或多张判断逻辑。灵活支持RGB摄像头设备的实时活体检测,可有效防止翻拍、头模、打印图片等样本攻击。简单易用:可直接调用的API接口,服务简单易用,易被集成,兼容性强。输入限制图像格式:PNG、JPG、JPEG、BMP、GIF、WEBP。图像大小:不超过10 MB。如您有大图需求,请通过钉钉群(23109592)联系我们。图像分辨率:建议大于256×256像素,像素过低可能会影响识别效果。URL地址中不能包含中文字符。检测说明最长检测时间是5秒,如果在该时间内没有完成检测,系统会强制返回超时错误码。图像下载时间限制为3秒,如果下载时间超过3秒,系统会返回下载超时。图像检测接口响应时间依赖图像的下载时间。请保证被检测图像所在的存储服务稳定可靠,建议您使用阿里云OSS存储或者CDN缓存。最多可检测10张图像。目前平台提供的活体检测为静默活体,即基于图片进行检测,暂不支持摇头,张嘴、眨眼等动作的活体检测。请求参数名称类型是否必选示例值描述ActionString是DetectLivingFace系统规定参数,取值为DetectLivingFaceTasks.N.ImageURLString否http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0.domepic/facebody/DetectLivingFace/DetectLivingFace4.jpg待检测的图像URL地址,JSON数组中的每个元素是一个图片检测任务结构体(image表),最多支持10个元素,即同时最多对10张图片进行检测。推荐使用上海地域的OSS链接Tasks.N.ImageDataString否/9j/4AAQSkZJRgABAQAAAQABAAD/2*图像Base64编码字符串,当与URL方式共存时,URL方式优先返回数据名称类型示例值描述RequestIdString2EA20206-E045-4329-8BED-00677F6EF738请求IDDataObject-返回的结果数据内容ElementsArray of Element-返回的元素ImageURLStringhttp://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0.domepic/facebody/DetectLivingFace/DetectLivingFace4.jpg对应请求中的图像URL地址TaskIdStringemplowerIdWuzhTestAPIt7aZ1**该检测任务的IDResultsArray of Result-返回结果,调用成功时返回结果中包含一个或多个元素SuggestionStringreview建议执行的操作,取值范围如下:pass:图片中的活体对象为直接拍摄的图,无需进行其他操作。review:图片中的活体对象可能是翻拍图,建议审核人员进行操作。block:图片中的活体对象为翻拍图,建议进行拦截操作。如果未检测到人脸,则Suggestion返回值为blockFramesArray of Frame-(仅宇视版)输入图像为长图(宽高比大于3:1)时,会把原图裁成几张近正方形的图,Frames保存从图像中截出来的图而且是截图中的裁剪图UrlStringhttp://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0.domepic/facebody/DetectLivingFace/DetectLivingFace4.jpg?x-oss-process=image/resize,m_lfit,w_500/auto-orient,1/quality,q_90命中的截图RateFloat84.83结果为该分段的概率,取值范围为0.00 - 100.00,取值越大,表示属于该分段的概率越大。如果未检测到人脸,则Rate返回值为0.00LabelStringliveness检测结果分段,取值包括:normal:活体图片liveness:翻拍图片如果未检测到人脸,则Label返回为livenessRateFloat76.22结果为该分段的概率,取值范围为0.00 - 100.00,取值越大,表示属于该分段的概率越大RectObject-人脸的坐标信息LeftLong20检测框左上角的x坐标TopLong30检测框左上角的y坐标WidthLong50检测框宽度HeightLong60检测框高度MessageTipsStringblurred, occluded or large angle face, please check.提示信息。如输入模糊图、遮挡图或大角度等的人脸,则返回提示信息:blurred, occluded or large angle face, please check.如未检测到人脸,则返回提示信息:no face detected, try again please.FaceNumberLong1原图片中检测到的人脸数量。如果未检测到人脸,FaceNumber返回为0活体阈值参考LabelRate阈值攻击拦截率活体通过率liveness5098.7%97.85%liveness3099.03%96.96%normal(推荐)80(推荐)99.17%96.39%normal8599.27%95.55%normal9599.53%92.24%当Label是normal时,表示的是活体,Rate表示活体置信度,Rate取值范围是[80,100]。当Label是liveness时,表示的是非活体,Rate表示非活体置信度,Rate取值范围是[20,100]。关于以上数值的概念定义:攻击拦截率:如98%,代表100次作弊假体攻击,会有98次被API识破拒绝。活体通过率:如98%,代表100次真人请求,会有98次顺利通过活体验证。HTTP/1.1 200 OK Content-Type:application/json { "RequestId" : "2EEA0396-BD84-5729-B8BD-D60776FCEF2B", "Data" : { "Elements" : [ { "ImageURL" : "http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/DetectLivingFace/DetectLivingFace4.jpg", "TaskId" : "img1owc8WGskNm78OEAPJTZal-1****", "Results" : [ { "Suggestion" : "review", "Frames" : [ { "Url" : "http://aligreen-shanghai.oss-cn-shanghai.aliyuncs.com/prod/hammal/26210da42/28118541_TB1urBOQFXXXXbMXFXXXXXXXXXX-1442-257.png?Expires=1582703593&OSSAccessKeyId=H4sp5QfNbuDg****&Signature=%2B8iUkb5YjomYR8ujV2c8wMAavs****&x-oss-process=image%2Fcrop%2Cx_0%2Cw_288%2Fauto-orient%2C0", "Rate" : 84.83 } ], "Label" : "liveness", "Rate" : 76.22, "Rect" : { "Left" : 20, "Top" : 30, "Width" : 50, "Height" : 60 }, "MessageTips" : "blurred, occluded or large angle face, please check." } ], "FaceNumber" : 1 } ] } }
2025年02月15日
20 阅读
0 评论
0 点赞
2025-02-15
删除数据库
功能描述删除数据库能力用于删除指定的人脸数据库。请求参数名称类型是否必选示例值描述ActionString是DeleteFaceDb系统规定参数,取值为DeleteFaceDbNameString是default数据库名称返回数据名称类型示例值描述RequestIdString203AE658-CFE1-507D-B105-F88CD1F1F71B请求IDHTTP/1.1 200 OK Content-Type:application/json { "RequestId" : "203AE658-CFE1-507D-B105-F88CD1F1F71B" }
2025年02月15日
22 阅读
0 评论
0 点赞
2025-02-15
删除人脸样本
功能描述删除人脸样本能力用于删除人脸数据库中的人脸样本数据。请求参数名称类型是否必选示例值描述ActionString是DeleteFaceEntity系统规定参数,取值为DeleteFaceEntityDbNameString是default数据库名称EntityIdString是wood实体ID,如员工编号,可包含数字、字母和下划线返回数据名称类型示例值描述RequestIdStringDA7CAFEB-0A37-4496-9CDF-E3DBB6309CB2请求IDHTTP/1.1 200 OK Content-Type:application/json { "RequestId" : "DA7CAFEB-0A37-4496-9CDF-E3DBB6309CB2" }
2025年02月15日
4 阅读
0 评论
0 点赞
1
2
3
...
23