2-使用wifidog实现portal
wifidog是openwrt上面实现portal认证的一个开源工具,从网关端到服务器都帮你搭建好,通过学习wifidog的原理,后面就可以改造成自己需要的逻辑。
1. openwrt安装wifidog
添加源
vim 14.07/feeds.conf.defaultsrc-git wifidog https://github.com/wifidog/wifidog-gateway.git
feed里面添加wifidog模块
github上面下载https://github.com/wifidog/wifidog-gateway,然后使用里面的/contrib/build-openwrt-kamikazeipk/wifidog内容添加到package下。
├── wifidog
│ ├── files
│ │ ├── wifidog.conf
│ │ └── wifidog.init
│ └── Makefile
.config添加
CONFIG_PACKAGE_wifidog=y
wifidog/Makefile 里面的版本可以自己修改
include $(TOPDIR)/rules.mkPKG_NAME:=wifidog
PKG_VERSION:=1.3.0
PKG_RELEASE:=1PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:= @SF/wifidog
PKG_MD5SUM:=PKG_FIXUP = libtoolinclude $(INCLUDE_DIR)/package.mk
...
2.修改配置文件
编译完成的wifidog烧录后,在/etc/wifidog.conf里面修改配置认证服务器信息
GatewayID default
ExternalInterface apclii0 //WAN口
GatewayInterface br-lan //LAN口
GatewayAddress 192.168.18.1 //LAN口IP
AuthServer {Hostname 192.168.3.185 //服务器地址SSLAvailable noSSLPort 443HTTPPort 80Path /LoginScriptPathFragment login/?PortalScriptPathFragment portal/?MsgScriptPathFragment gw_message.php?PingScriptPathFragment ping/?AuthScriptPathFragment auth/?
}//可以有多个AuthServer,Wifidog会从第一个往后找,直到找到可用的认证服务器为止。# Listen on this port
GatewayPort 2060ProxyPort 0
HTTPDMaxConn 10
HTTPDRealm WiFiDog
HTTPDUserName admin
HTTPDPassword secretCheckInterval 60
ClientTimeout 5FirewallRuleSet validating-users {FirewallRule allow to 0.0.0.0/0
}FirewallRuleSet known-users {FirewallRule allow to 0.0.0.0/0
}FirewallRuleSet unknown-users {FirewallRule allow udp port 53FirewallRule allow tcp port 53FirewallRule allow udp port 67FirewallRule allow tcp port 67
}FirewallRuleSet locked-users {FirewallRule block to 0.0.0.0/0
}
配置好wifidog.conf后即可启动wifidog
/etc/init.d/wifidog restart
在vim /usr/bin/wifidog-init里面可以把debug打开
OPTIONS="-d7"
3.服务器搭建
在官网下面有搭建过程,不过实际搭建的时候回发现有一些不一样:
http://dev.wifidog.org/wiki/doc/install/ubuntu/auth-server
1 安装apache2、php5、数据库
apache2是代理服务器,php5是wifidog的后台web使用的语言
sudo apt-get update
sudo apt-get install apache2 php5
sudo apt-get install postgresql
sudo apt-get install php5-cgi
sudo apt-get install php5-mhash php5-pgsql php-pear php5-xmlrpc php5-curl php5-mcrypt php5-dev
sudo apt-get install language-pack-en-base
sudo apt-get install openssh-server
2 下载wifidig服务器代码
克隆代码
git clone https://github.com/wifidog/wifidog-auth
拷贝到apach2目录下
sudo mv wifidog-auth/ /var/www/
最新的wifidog-auth不用改下以下信息
hange line 122 to the following:'website' => "http://www.smarty.net/",
Change line 123 to the following: 'installSourceUrl' => "http://www.smarty.net/files/Smarty-2.6.26.tar.gz",
修改sudo vim /var/www/wifidog-auth/wifidog/config.php里面的fr_CA
define('DEFAULT_LANG', 'en_US');
将apach2的默认目录改成wifidog的目录路径
需要找下DocumentRoot设置的路径,我的在/etc/apache2/sites-available/000-default.conf里面
DocumentRoot /var/www/wifidog-auth/wifidog
修改完重启apach2
sudo /etc/init.d/apache2 restart
3 从web安装wifidog-auth
上面都安装好后,web访问本地地址http://localhost/install.php

点击install下一步,会提示输入账号密码
账号密码位于cat /tmp/dog_cookie.txt下面
4.交互过程
先介绍一下wifidog与Auth服务器的交互协议:
1 首先是重定向,在首次登陆时,用户访问的url会被重定向到如下的地址:
login/?gw_address=%s&gw_port=%d&gw_id=%s&url=%s(2009版本的wifidog)login/?gw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s(2013版本的wifidog)实际数据:
http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.145&mac=20:ab:37:8d:c2:f6&url=http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html
这里有一个版本的问题,即2009的wifidog在重定向时不会在链接中带上mac参数,而2013版本的wifidog是会带上的,所以这里需要根据自己的应用特别注意。
在用户首次连接路由上网时,它访问的url会被定向到login页面,并带上如上所述的参数,我们可以利用这些参数做生成token或其它一些判断等。而通常情况是在login中向用户返回通过wifi认证的方法,如带有用户名和密码的登录页面等。
重定向的代码位于wifidog的http.c里面,会返回302暂时重定向代码。
http_send_redirect(request * r, const char *url, const char *text)
{char *message = NULL;char *header = NULL;char *response = NULL;/* Re-direct them to auth server */debug(LOG_DEBUG, "Redirecting client browser to %s", url);safe_asprintf(&header, "Location: %s", url);safe_asprintf(&response, "302 %s\n", text ? text : "Redirecting");httpdSetResponse(r, response);httpdAddHeader(r, header);free(response);free(header);safe_asprintf(&message, "Please <a href='%s'>click here</a>.", url);send_http_page(r, text ? text : "Redirection to message", message);free(message);
}
2 用户认证协议:
auth_server:/auth/auth.php?stage=%s&ip=%s&mac=%s&token=%s&incoming=%s&outgoing=%s
一般情况下,认证服务器auth_server会根据用户输入的信息生成一个token,然后将用户重定向到wifidog的监听端口上,这个端口的默认地址为:192.168.1.1:2060/wifidog/auth?token=%s。
wifidog得到这个token后,将其发送到auth_server认证服务器上进行认证。如果认证通过,auth_server返回“Auth: 1”,认证未通过则返回“Auth: 0”。具体参数如下。
认证服务器通过获取以上链接的参数可以判断这个用户是否合法等。这个链接是认证服务器用来判断首次登陆的用户是否合法和正在连接的用户是否可以继续访问链接的方法。
每隔一段时间,wifidog会向认证服务器发送信息,即通过如上所示的链接发送信息,通过这些参数,可以看到某个客户的上传流量、下载流量、mac地址、ip地址、token和、ip和stage。stage可能是两个参数,分别是counters或login。第一次登陆验证时,stage=login,其它时候stage=counters。
3 Ping协议
http://auth_sever/ping/?gw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu
wifidog会向认证服务器发送一些信息,来报告wifidog现在的情况,这些信息是通过Http协议发送的,如上的链接所示,参数大概如字面意思,没仔细研究过,而作为认证服务器,auth_server应回应一个“Pong”。
4 认证成功后的跳转
portal/?gw_id=%s
在认证成功后,wifidog会将用户重定向至该页面。
5.若验证失败,则会根据失败原因跳转至如下页面
gw_message.php?message=deniedgw_message.php?message=activategw_message.php?message=failed_validation
注意一下,按照我对wifidog.conf的配置,在执行login时,相当于重定向至链接http://justyoung.com/wifidog/login.php?gw_id=XX…等等,其它执行的链接也是如此。
新的连接加入时,log如下:
[6][Mon Jun 22 18:16:20 2020][19347](gateway.c:469) Received connection from 192.168.18.145, spawning worker thread
[7][Mon Jun 22 18:16:20 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.145
[7][Mon Jun 22 18:16:20 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.145
[6][Mon Jun 22 18:16:20 2020][19347](http.c:117) Got client MAC address for ip 192.168.18.145: 20:ab:37:8d:c2:f6
[6][Mon Jun 22 18:16:20 2020][19347](http.c:125) Check host captive.apple.com is in whitelist or not
[6][Mon Jun 22 18:16:20 2020][19347](http.c:162) Captured 192.168.18.145 requesting [http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html] and re-directing them to login page
[7][Mon Jun 22 18:16:20 2020][19347](http.c:240) Redirecting client browser to http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.145&mac=20:ab:37:8d:c2:f6&url=http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html
[7][Mon Jun 22 18:16:20 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.145
[7][Mon Jun 22 18:16:20 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.145
[6][Mon Jun 22 18:16:22 2020][19347](gateway.c:469) Received connection from 192.168.18.145, spawning worker thread
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.145
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.145
[6][Mon Jun 22 18:16:22 2020][19347](http.c:117) Got client MAC address for ip 192.168.18.145: 20:ab:37:8d:c2:f6
[6][Mon Jun 22 18:16:22 2020][19347](http.c:125) Check host captive.apple.com is in whitelist or not
[6][Mon Jun 22 18:16:22 2020][19347](http.c:162) Captured 192.168.18.145 requesting [http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html] and re-directing them to login page
[7][Mon Jun 22 18:16:22 2020][19347](http.c:240) Redirecting client browser to http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.145&mac=20:ab:37:8d:c2:f6&url=http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.145
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.145
[6][Mon Jun 22 18:16:22 2020][19347](gateway.c:469) Received connection from 192.168.18.233, spawning worker thread
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.233
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:22 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.233
[6][Mon Jun 22 18:16:24 2020][19347](gateway.c:469) Received connection from 192.168.18.145, spawning worker thread
[7][Mon Jun 22 18:16:24 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.145
[7][Mon Jun 22 18:16:24 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.145
[6][Mon Jun 22 18:16:24 2020][19347](http.c:117) Got client MAC address for ip 192.168.18.145: 20:ab:37:8d:c2:f6
[6][Mon Jun 22 18:16:24 2020][19347](http.c:125) Check host captive.apple.com is in whitelist or not
[6][Mon Jun 22 18:16:24 2020][19347](http.c:162) Captured 192.168.18.145 requesting [http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html] and re-directing them to login page
[7][Mon Jun 22 18:16:24 2020][19347](http.c:240) Redirecting client browser to http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.145&mac=20:ab:37:8d:c2:f6&url=http%3A%2F%2Fcaptive.apple.com%2Fhotspot-detect.html
[7][Mon Jun 22 18:16:24 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.145
[7][Mon Jun 22 18:16:24 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.145
[6][Mon Jun 22 18:16:27 2020][19347](gateway.c:469) Received connection from 192.168.18.231, spawning worker thread
[7][Mon Jun 22 18:16:27 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.231
[7][Mon Jun 22 18:16:27 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:27 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:27 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.231
[6][Mon Jun 22 18:16:32 2020][19347](gateway.c:469) Received connection from 192.168.18.233, spawning worker thread
[7][Mon Jun 22 18:16:32 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.233
[7][Mon Jun 22 18:16:32 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:32 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:32 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.233
[6][Mon Jun 22 18:16:35 2020][19347](gateway.c:469) Received connection from 192.168.18.233, spawning worker thread
[7][Mon Jun 22 18:16:35 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.233
[7][Mon Jun 22 18:16:35 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.233
[6][Mon Jun 22 18:16:35 2020][19347](http.c:117) Got client MAC address for ip 192.168.18.233: d0:17:c2:9a:b7:d1
[6][Mon Jun 22 18:16:35 2020][19347](http.c:125) Check host weixin.qq.com is in whitelist or not
[6][Mon Jun 22 18:16:35 2020][19347](http.c:162) Captured 192.168.18.233 requesting [http%3A%2F%2Fweixin.qq.com%2F] and re-directing them to login page
[7][Mon Jun 22 18:16:35 2020][19347](http.c:240) Redirecting client browser to http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.233&mac=d0:17:c2:9a:b7:d1&url=http%3A%2F%2Fweixin.qq.com%2F
[7][Mon Jun 22 18:16:35 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:35 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.233
[6][Mon Jun 22 18:16:36 2020][19347](gateway.c:469) Received connection from 192.168.18.231, spawning worker thread
[7][Mon Jun 22 18:16:36 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.231
[7][Mon Jun 22 18:16:36 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:36 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:36 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.231
[6][Mon Jun 22 18:16:40 2020][19347](gateway.c:469) Received connection from 192.168.18.233, spawning worker thread
[7][Mon Jun 22 18:16:40 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.233
[7][Mon Jun 22 18:16:40 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.233
[6][Mon Jun 22 18:16:40 2020][19347](http.c:117) Got client MAC address for ip 192.168.18.233: d0:17:c2:9a:b7:d1
[6][Mon Jun 22 18:16:40 2020][19347](http.c:125) Check host weixin.qq.com is in whitelist or not
[6][Mon Jun 22 18:16:40 2020][19347](http.c:162) Captured 192.168.18.233 requesting [http%3A%2F%2Fweixin.qq.com%2F] and re-directing them to login page
[7][Mon Jun 22 18:16:40 2020][19347](http.c:240) Redirecting client browser to http://192.168.3.185:80/wifidog/login/?gw_address=192.168.18.1&gw_port=2060&gw_id=default&ip=192.168.18.233&mac=d0:17:c2:9a:b7:d1&url=http%3A%2F%2Fweixin.qq.com%2F
[7][Mon Jun 22 18:16:40 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.233
[7][Mon Jun 22 18:16:40 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.233
[6][Mon Jun 22 18:16:45 2020][19347](gateway.c:469) Received connection from 192.168.18.231, spawning worker thread
[7][Mon Jun 22 18:16:45 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.231
[7][Mon Jun 22 18:16:45 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:45 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:45 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.231
[6][Mon Jun 22 18:16:54 2020][19347](gateway.c:469) Received connection from 192.168.18.231, spawning worker thread
[7][Mon Jun 22 18:16:54 2020][19347](httpd_thread.c:65) Processing request from 192.168.18.231
[7][Mon Jun 22 18:16:54 2020][19347](httpd_thread.c:66) Calling httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:54 2020][19347](httpd_thread.c:68) Returned from httpdProcessRequest() for 192.168.18.231
[7][Mon Jun 22 18:16:54 2020][19347](httpd_thread.c:73) Closing connection with 192.168.18.231
参考文档
wifidog官网:
https://sources.openwrt.org/
http://dev.wifidog.org/wiki/Download
https://github.com/wifidog/wifidog-gateway
https://www.jianshu.com/u/3c937c88e6c0
https://blog.csdn.net/just_young/article/details/38003015
相关文章:
2-使用wifidog实现portal
wifidog是openwrt上面实现portal认证的一个开源工具,从网关端到服务器都帮你搭建好,通过学习wifidog的原理,后面就可以改造成自己需要的逻辑。 1. openwrt安装wifidog 添加源 vim 14.07/feeds.conf.defaultsrc-git wifidog https://github.c…...
Spring Boot + ShardingSphere 踩坑记
最近在准备秋招,偷了个轮子项目之后想改个分表,于是有了这篇文章。 省流:请使用shardingsphere-jdbc 5.5.2,并根据官方5.5.2版本文档进行配置,不要使用starter。此外,如果希望使用INTERVAL分片算法&#x…...
AI时代前端开发的创造力:解放还是束缚?
在人工智能(AI)快速发展的时代,AI技术的影响已经渗透到各个领域,从医疗保健到金融服务,再到创意产业。AI工具的出现,为前端开发带来了前所未有的效率提升,但也引发了人们对创造力的担忧…...
有哪些免费的SEO软件优化工具
随着2025年互联网的不断发展,越来越多的企业意识到在数字营销中,网站的曝光度和排名至关重要。无论是想要提高品牌知名度,还是想要通过在线销售增加收益,SEO(搜索引擎优化)都是一项不可忽视的关键策略。而要…...
FastExcel + Java:打造高效灵活的Excel数据导入导出解决方案
作者:后端小肥肠 🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: 基于AOP的数据字典实现…...
在Vue中,JavaScript数组常用方法,添加,插入,查找,删除等整理
在Vue中,JavaScript数组常用,添加,插入,查找,删除等整理 1.splice()方法可以直接修改原数组,通过指定要删除元素的索引来删除它。 例: let index // 要删除的元素的索引; this.array.splice(i…...
vue知识点2
1.methods和mounted的区别 methods是定义方法,不涉及到调用 mounted涉及到操作 所以methods后面是:,mounted后面是() 2.介绍一下emit的用法 如果子控件要调用父页面的方法,在父页面的子控件引用处&…...
node.js + html调用ChatGPTApi实现Ai网站demo(带源码)
文章目录 前言一、demo演示二、node.js 使用步骤1.引入库2.引入包 前端HTML调用接口和UI所有文件总结 前言 关注博主,学习每天一个小demo 今天是Ai对话网站 又到了每天一个小demo的时候咯,前面我写了多人实时对话demo、和视频转换demo,今天…...
14.Python生成器、迭代器、闭包、装饰器、元类、垃圾回收、内建函数
在 Python 中,生成器、迭代器、闭包、装饰器、元类、垃圾回收和内建函数是一些重要的概念和功能,它们对于编写高效、灵活的代码非常重要。下面我们逐一详细介绍这些概念及其用法。 1. 生成器(Generator) 生成器是一个函数&#…...
STM32+Proteus+DS18B20数码管仿真实验
1. 实验准备 硬件方面: 了解 STM32 单片机的基本原理和使用方法,本实验可选用常见的 STM32F103 系列。熟悉 DS18B20 温度传感器的工作原理和通信协议(单总线协议)。数码管可选用共阴极或共阳极数码管,用于显示温度值。…...
Vulhub靶机 ActiveMQ 反序列化漏洞(CVE-2015-5254)(渗透测试详解)
一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 漏洞版本:Apache ActiveMQ 5.x ~ Apache ActiveMQ 5.13.0 二、访问靶机IP 8161端口 默认账户密码 admin/admin,登录 此时qucues事件为空 1、使用jmet-0.1.0-all.jar工具将…...
ConcurrentHashMap扩容
目录 一、tryPreSize方法-初始化数组 二、tryPreSize方法-扩容标识戳 三、transfer方法-构建新数组 四、transfer方法-迁移数据 五、transfer方法-lastRun机制 六、helpTransfer方法-协助扩容 三种触发方式 达到了扩容的阈值 一、tryPreSize方法-初始化数组 // 扩容前…...
2025年二级建造师报名流程图解
2025年二级建造师报名时间!附报名流程! ⏰️已公布25年二建考试时间的省份如下: ️4月19日、20日考试的城市有:贵州 ️5月10日、11日考试的城市有:湖北、陕西、宁夏、甘肃、福建、浙江、江西、黑龙江、河南、湖南、…...
【自学笔记】人工智能基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 人工智能重点知识点总览一、基础概念与原理1.1 人工智能定义与发展1.2 算法与数据结构1.3 数学基础 二、机器学习2.1 监督学习2.2 无监督学习2.3 强化学习 三、深度…...
hexo 魔改 | 修改卡片透明度
hexo 魔改 | 修改卡片透明度 ** 博客食物用更佳 博客地址 ** 这是笔者自己瞎倒腾的。作为前端菜鸡一枚,大佬们随便看看就好~ 我用的主题是 butterfly 4.12.0 分析 通过开发者工具可以看出来卡片的背景和 --card-bg 变量有关 再在 sources 下的 css 文件夹下的…...
Golang的并发编程案例详解
Golang的并发编程案例详解 一、并发编程概述 并发编程是指程序中有多个独立的执行线索,并且这些线索在时间上是重叠的。在 Golang 中,并发是其核心特性之一,通过 goroutine 和 channel 来支持并发编程,使得程序可以更高效地利用计…...
【升级】阿里云对象存储 HTTPS 根证书升级公告
--时间打败一切...
贪心算法与动态规划的区别
贪心算法:每一步都选择当前最优解,期望通过局部最优达到全局最优。 动态规划:通过分解问题为子问题,存储并重用子问题的解,避免重复计算。 最简单的JS ACM代码举例 贪心算法:找零问题 function greed…...
策略模式-小结
总结一下看到的策略模式: A:一个含有一个方法的接口 B:具体的实行方式行为1,2,3,实现上面的接口。 C:一个环境类(或者上下文类),形式可以是:工厂模式,构造器注入模式,枚举模式。 …...
TDengine 性能测试工具 taosBenchmark
简介工具获取运行 无参数模式命令行模式配置文件模式 命令行参数配置文件参数 通用配置参数写入配置参数 数据库相关超级表相关标签列与数据列写入行为相关 查询配置参数 执行指定查询语句查询超级表 订阅配置参数数据类型对照表 配置文件示例 写入 JSON 示例查询 JSON 示例订阅…...
硬件学习笔记--41 电磁兼容试验-5 射频场感应的传导干扰试验介绍
目录 电磁兼容试验-射频场感应的传导干扰试验介绍 1.试验目的 2.试验方法 3.判定依据及意义 电磁兼容试验-射频场感应的传导干扰试验介绍 驻留时间是在规定频率下影响量施加的持续时间。被试设备(EUT)在经受扫频频带的电磁影响量或电磁干扰的情况下&a…...
泛型 类 接口 方法 通配符
泛型 泛型类 what: 类型参数化 why use: 1. 输出时候是object类型 而不是真正类型转化麻烦 import java.util.ArrayList; import java.util.List;public class ObjectExample {public static void main(String[] args) {List<Object> list new ArrayLi…...
文字转语音(三)FreeTTS实现
项目中有相关的功能,就简单研究了一下。 说明 FreeTTS 是一个基于 Java 的开源文本转语音(TTS)引擎,旨在将文字内容转换为自然语音输出。 FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景,但若需…...
STM32 RTC 实时时钟说明
目录 背景 RTC(实时时钟)和后备寄存器 32.768HZ 如何产生1S定时 RTC配置程序 第一次上电RTC配置 第1步、启用备用寄存器外设时钟和PWR外设时钟 第2步、使能RTC和备份寄存器访问 第3步、备份寄存器初始化 第4步、开启LSE 第5步、等待LSE启动后稳定状态 第6步、配置LSE为…...
Open-R1 项目代码文件的详细剖析
目录 1. configs.py 功能概述 关键代码与细节 2. evaluate.py 功能概述 关键代码与细节 3. generate.py 功能概述 关键代码与细节 4. grpo.py 功能概述 关键代码与细节 5. rewards.py 功能概述 关键代码与细节 6. sft.py 功能概述 关键代码与细节 安装 训练…...
Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)
Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1) import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…...
【DuodooBMS】基于Odoo的开源制造执行系统——以开源之力,驱动智能制造
以用户为中心的开放式智造平台 DuodooMES的设计始终围绕“用户可编程、生态可生长”的核心思想,打破传统工业软件的封闭性,让制造企业真正成为系统的“主人”: 1. 用户可编程:生产流程由你定义 界面可配置:无需代码即…...
机器视觉深度学习,工业缺陷检测中数据标注需要注意那些问题
在工业缺陷检测中,数据标注是构建高质量模型的关键步骤,需注意以下问题: 标注准确性 精确标注缺陷位置:确保标注框或掩码准确覆盖缺陷区域,避免过大或过小。 区分缺陷类型:不同缺陷应有明确分类,避免混淆。标注一致性 统一标注标准:制定并遵循统一的标注规范,确保不同…...
数据结构:图论入门
图论起源于欧拉对哥尼斯堡七桥问题的解决. 他构建的图模型将陆地用点来表示, 桥梁则用线表示, 如此一来, 该问题便转化为在图中能否不重复地遍历每条边的问题. 图论的应用 地图着色 在地图着色问题中, 我们用顶点代表国家, 将相邻国家之间用边相连. 这样, 问题就转化为用最少…...
【R语言】方差分析
一、基本术语 在R语言以及更广泛的统计学领域中,方差分析(ANOVA,即Analysis of Variance)是一种用于比较两个或更多组数据的均值是否存在显著差异的统计方法。可以使用aov()函数或其他相关函数(如anova())…...
