无锡的项目搞的差不多了,从忙碌的疯狂进代码的阶段进入了短暂的空闲期。
啤酒城的项目今年没有啥大的改动,等合同敲定,活动开业前,把服务器重新部署上线即可。
不夜城街区的项目,肥城的已经完成,等剑阁项目和临夏项目开业,服务器部署一下,活也不是太多。
那么,得琢磨个事情干干,这段空档期干点啥好呢~
软件的版本,又何尝不是人生的版本呢?
无锡的项目搞的差不多了,从忙碌的疯狂进代码的阶段进入了短暂的空闲期。
啤酒城的项目今年没有啥大的改动,等合同敲定,活动开业前,把服务器重新部署上线即可。
不夜城街区的项目,肥城的已经完成,等剑阁项目和临夏项目开业,服务器部署一下,活也不是太多。
那么,得琢磨个事情干干,这段空档期干点啥好呢~
软件的版本,又何尝不是人生的版本呢?
最近在把分散在各地的项目进行了整合,计划合并到一个服务器上,搬家工作搞了整整一天。
研究了一番,最后把去年项目剩的服务器全给取消了,买了一个阿里云的云小站 https://www.aliyun.com/minisite/goods 的ECS。
配置有两种:
2核2G,3M固定带宽,40G ESSD Entry云盘 ¥99.00/1年起 官网折扣价: ¥956.64/1年
2核4G,5M固定带宽,80G ESSD Entry云盘 ¥199.00/1年起 官网折扣价: ¥2507.70/1年
物超所值,几乎不到1折的价格,更重要的是,能不限年限的续费,一个账户只能嫖一个。
直接199的配置走起,2核4G完全够用。跑了两个Python Flask, 两个Python FastAPI, 两个静态site,还能剩余2.2G内存,妥妥够用。
感谢阿里云~
PyCharm里如果有js, html 和css文件,社区版本的IDE是不能直接格式化这些静态文件,需要专业版的来实现。
所以,可以尝试在terminal里直接使用prettier格式化代码。
1 | # 用node全局安装 |
1 | from functools import lru_cache |
使用了 @lru_cache 装饰器,因此只有在第一次调用它时,才会创建 Settings 对象一次。
然后,在下一次请求的依赖项中对 get_settings() 进行任何后续调用时,它不会执行 get_settings() 的内部代码并创建新的 Settings 对象,而是返回在第一次调用时返回的相同对象,一次又一次。
@lru_cache 修改了它所装饰的函数,以返回第一次返回的相同值,而不是再次计算它,每次都执行函数的代码。
因此,下面的函数将对每个参数组合执行一次。然后,每个参数组合返回的值将在使用完全相同的参数组合调用函数时再次使用。
对于我们的依赖项 get_settings(),该函数甚至不接受任何参数,因此它始终返回相同的值。
这样,它的行为几乎就像是一个全局变量。但是由于它使用了依赖项函数,因此我们可以轻松地进行测试时的覆盖。
@lru_cache 是 functools 的一部分,它是 Python 标准库的一部分,可以在 Python 文档 lru_cache中了解有关 @lru_cache 的更多信息。
今天学习FastAPI时,细致了解了一下时差攻击。
什么是时差攻击?
假设攻击者试图猜出用户名与密码。
他们发送用户名为 johndoe,密码为 love123 的请求。
然后,Python 代码执行如下操作:
1 | if "johndoe" == "stanleyjobson" and "love123" == "swordfish": |
但就在 Python 比较完 johndoe 的第一个字母 j 与 stanleyjobson 的 s 时,Python 就已经知道这两个字符串不相同了,它会这么想,没必要浪费更多时间执行剩余字母的对比计算了。应用立刻就会返回错误的用户或密码。
但接下来,攻击者继续尝试 stanleyjobsox 和 密码 love123。
应用代码会执行类似下面的操作:
1 | if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish": |
此时,Python 要对比 stanleyjobsox 与 stanleyjobson 中的 stanleyjobso,才能知道这两个字符串不一样。因此会多花费几微秒来返回错误的用户或密码。
通过服务器花费了更多微秒才发送错误的用户或密码响应,攻击者会知道猜对了一些内容,起码开头字母是正确的。
然后,他们就可以放弃 johndoe,再用类似 stanleyjobsox 的内容进行尝试。
当然,攻击者不用手动操作,而是编写每秒能执行成千上万次测试的攻击程序,每次都会找到更多正确字符。
但是,攻击者利用时间差,就能在几分钟或几小时内,以这种方式猜出正确的用户名和密码。
在此,代码中使用了 secrets.compare_digest()。
简单的说,它使用相同的时间对比 stanleyjobsox 和 stanleyjobson,还有 johndoe 和 stanleyjobson。对比密码时也一样。
在代码中使用 secrets.compare_digest() ,就可以安全地防御全面攻击了。
1 | current_username_bytes = credentials.username.encode("utf8") |
发现了一个非常好用的代码格式化工具:Ruff。
Ruff是一个基于Python的代码格式化工具,它可以帮助开发者格式化Python代码,使其符合PEP 8标准。
Pip安装:
1 | pip install ruff |
使用:
1 | ruff format <file> |
把所有的项目都用ruff格式化了一遍,快到难以想象,几百个文件的项目,一两秒钟就格式化好了。
闲来无事打了一会CS,发现自动购买按了F1以后,只买了主武器,甚至子弹都没有补满,研究了一下发现游戏文件里有个
1 | // This list of "buy aliases" is used by the AutoBuy system. |
这里面定义了自动购买的时候要买的武器和装备,直接改一下,增加一下需要的配置就可以了,闪光灯这里买两个。
保存文件,重新启动游戏就可以了。
在一个历史项目上有一个新需求,当客流到达一定整万数的时候,来一个页面特殊效果,于是决定做一个烟花的效果出来。
研究了一下,找到一个项目 https://www.kirilv.com/canvas-confetti/ ,最后的实现效果还不错。
1 |
|
做完这个以后,后面发现还有一个朋友 Caleb Miller 做的几乎一比一仿真的烟花效果,记录一下。
https://codepen.io/MillerTime/pen/XgpNwb
重装了一次电脑,记录一下git alias的配置。
1 | $ cat ~/.gitconfig |
顺手记录一下:
Thinkbook 14+ 使用U盘启动的时候,F12以后引导选择后,无法正常启动。需要F1选择把安全启动模式给关掉就可以了。
新的项目需要去一个网站上获取一些数据,做一个爬虫,网站上有验证码,以前的时候简单的验证码可以直接使用tesseract直接识别,但是这次的验证码长这个样子:
尝试了几次OCR的解决方案,发现不能成功,这里面有斜线干扰,数字是彩色的,且歪歪扭扭的。
所以计划使用tensorflow训练个模型,在尝试的过程中发现了一个参数都已经调好的python lib, CaptchaCracker。
训练的时候,需要调整的参数不是很多,只需要给定验证码的图片宽度高度就可以了。
1 | import glob |
利用脚本从网站上获取了1000多的验证码图片,批量命令后,利用excel记录标记的结果,这个过程比较辛苦,需要一点一点的标记所有的图片。
标记了1500张图,基本上样本就够了,因为这个验证码的范围是0-8,且只是4位数字。
开始运行训练代码后,我的电脑ntel(R) Core(TM) Ultra 5 (16核), 32G内存,跑了大概十来分钟,生成了一个.h5的模型文件。
下面的代码是使用模型识别新的验证码图片,同样也是需要设置一下验证码图片的高度宽度,数字长度,字符的识别范围。
应用模型后,就可以识别出来结果了。
1 | import os |
最后的识别效果还是非常棒的,基本能到95%以上的成功率。