图片来源:https://www.pixiv.net/artworks/81733152 使用sed处理类似下面这样的有独立的首尾特征的多行结构数据,实现增删改查 增 给梨添加一个产地字段(from = guangxi) 删 删除苹果的产地 改 修改香蕉的价格 查 打印所有打折的水果(on_sale = true) 单行版本 多行版本 参考:
图片来源:https://www.pixiv.net/artworks/81818784 PCAPdroid下载安装 PCAPdroid是一个Android端抓包软件,可以不使用root权限,通过VPN的方式捕获网络流量并保存为pcap文件。但以这种方式保存的报文没有Enternet数据,可以通过tcprewrite修改报文,添加Enternet报文头 安装包下载链接: 抓包 Linux上使用tcprewrite添加Enternet报文头 tcprewrite工具包含在tcpreplay包里,安装tcpreplay即可 安装 Arch Linux Ubuntu 重写报文数据 将手机上抓包保存的pcap文件传到PC上,使用下面的命令添加Enternet报文头 另外我在Arch Linux上使用安装的“tcpreplay-4.4.2”存在重写失败的情况,回退到“tcpreplay-4.3.1”后则没有问题
图片来源:https://www.pixiv.net/artworks/85222177 极简CMakeLists.txt 设置编译使用的C++标准 设置项目名称和版本 编译时自动生成包含版本号宏定义的头文件 添加INCLUDE路径 编译为静态库 链接库 让使用MathFunctions库的地方自动添加使用MathFunctions库必要的include路径 参考:
图片来源:https://www.pixiv.net/en/artworks/101040610 基本语法 getopts用来在shell脚本中解析命令行传入的选项 optstring optstring指定要解析哪些选项,哪些选项需要额外参数(如-f选项需要一个用户指定的文件名),需要额外参数的选项后面添加冒号 比如下面这条命令,使用tar创建一个tar包“test.tar” 其中, c选项表示“创建”,不需要参数;f选项指定生成的文件名,需要参数。所以解析这两个选项的optstring应该写成 特殊变量 解析错误 示例 下面编写一个简单的备份文件脚本,演示getopts的用法 脚本的基本功能和用法: 参考:
图片来源:https://www.pixiv.net/en/artworks/65883716 TL;DR 语法 含义 const T* 指向 const 对象的指针 T* const 指向对象的 const 指针 const T* const 指向 const 对象的 const 指针 吐槽“指针常量”和“常量指针” 这两个概念本身的含义都很简单,但所谓“指针常量”和“常量指针”的说法却将这两个概念理解和记忆难度成倍提升了。每当只看这两个中文,想要“顾名思义”的时候,我总会陷入混乱: 常量指针: 既可以理解为指向某个常量的指针(const T *),也可以理解为“常量”是对“指针”的修饰(T *const) 指针常量: 这个倒没什么歧义,像“整型常量”一样去理解就行,但定义语法看起来却又和整型常量完全不同:整形常量(const int), 指针常量(int *const) 当然如果只是以上这样,只要能做到概念统一的话那倒也没什么,权当我自己脑抽了,但好死不死《C++ Primer中文版(第5版)》里对这两个概念的英文直译又和百度百科里的定义完全相反 百度百科的定义 常量指针:const T * 指针常量:T * const 《C++ Primer》里的定义 指向常量的指针(pointer to const):const T * 常量指针(const pointer):T * const 另外,如果采用“指针常量”和“常量指针”的说法,当遇到“const T * const”时,是不是该叫“常量指针常量”😅(当然网上看到的说法大多为“指向常量的常指针”、“指向常量的指针常量”) 官方文档里的定义 当前的C++官方文档“指针声明”这一章的中文翻译里并没有上面这两个说法,取而代之的是“指向 const 对象的指针(pointer to constant object)”和“指向对象的 const 指针(constant pointer to object)” 指向 const 对象的指针:指针变量本身可以修改(即可以指向不同对象),但不能修改“指向的对象”里的内容(即对于指针p来说, “p = &a”可行,“*p = a”不可行) 指向对象的 const 指针:指针变量本身初始化后不可再修改(即不能指向其他对象),但可以修改“指向的对象”里的内容(即对于指针p来说, “p = &a”不可行,“*p = a”可行) 语法 含义 const T* 指向 const 对象的指针 T const* 指向 const 对象的指针 T* const 指向对象的 const 指针 const T* const 指向 const 对象的 const 指针 T const* const 指向 const 对象的 const 指针 指针声明语法 […]
图片来源:https://www.pixiv.net/artworks/97882990 基本 文件后缀 .dot或者.gv 节点和边 无向图 有向图 注释 命令行渲染命令 子图(subgraph)和集群(cluster) 可以用“{}”创建一个匿名的子图,仅仅起到语句块的作用 可以给子图设置“集群”属性让graphviz给子图渲染一个边框,设置方法有两种 子图中定义的节点也是全局共享的 属性(Attributes) 方向 属性名:rankdir 作用:设置渲染开始方向 可选值:TB(默认), LR, BT, RL 标签 属性名:lable 作用:设置图、子图、节点、边等显示的内容 节点形状 属性名:shape 作用:设置节点形状 可选值:值较多,参看https://graphviz.org/doc/info/shapes.html#polygon 其他 Graphviz画树的输出优化脚本 优化命令,其中tree.g文件即为Emden Gansner大佬的优化脚本 参考:
图片来源:《侦探已经死了》第一集截图 使用的Android设备为一加7Pro, 刷机和root流程:Linux下给一加7Pro刷入LineageOS、获取root权限 不需要root权限的抓包方法:Android手机4G网络抓包(no-root) 方案一(仅使用手机):安装配置Termux Termux下载地址:官方github仓库, GooglePlay(不推荐,版本较老), Fdroid, apkmirror 配置 打开Termux 获取存储权限,并且会在家目录下生成storage文件夹,里面包含downloads等手机共享目录的软连接方便使用 先更新一波,更新过程中可能会有多次提示配置文件覆盖需要你选择,直接回车默认是不覆盖,也可以输入“Y”选择覆盖,建议覆盖 添加root仓库 安装sudo工具 安装tcpdump 抓包 运行tcpdump开始抓包,然后切换到需要抓包的应用开始操作即可 “Ctrl+C”停止抓包,这样抓到的报文就会保存在系统下载目录的“xxx.pcap”文件中 这样抓的包以太网协议头会被替换成伪协议“Linux cooked capture”,需要的话可以进行转换,转换方法见文末 方案二:使用tcpdump和PC端wireshark抓包 注意:LineageOS支持下面的操作,但很多国内厂商的手机系统,即使root了也无法进行下面的操作,原因和解决方案请自行参看https://stackoverflow.com/questions/25271878/android-adbd-cannot-run-as-root-in-production-builds 安装adb Arch Linux Ubuntu 安装tcpdump到手机 访问https://www.androidtcpdump.com/android-tcpdump/downloads, 下载“tcpdump for ARM Android” 手机打开“USB调试”、“Root身份调试”,数据线连接手机和电脑,进入存放刚刚下载的tcpdump的目录,执行 抓包 确保adbd运行在root模式 电脑上打开wireshark,能看到很多“Android tcpdump”开头的网卡(Android tcpdump 后面跟的第一个单词才是真的网卡名字) 候选网卡比较多,可以一个个试,移动数据网络一般是“rmnet_dataN”(N是个数字,关闭“移动数据”再打开可能会变),我的是“rmnet_data3”,双击即可开始抓包 和方案一一样,这样抓的包以太网协议头会被替换成伪协议“Linux cooked capture”,需要的话可以进行转换,转换方法见文末 Linux cooked-mode capture (SLL)格式转换 使用“tcprewrite”重写数据即可,“tcprewrite”包含在“tcpreplay”包中 安装 Arch Linux Ubuntu 转换 另外我在Arch Linux上使用安装的“tcpreplay-4.4.2”存在转换失败的情况,回退到“tcpreplay-4.3.1”后则没有问题 参考:
图片来源:https://www.pixiv.net/artworks/86467376 安装 安装adb Arch Linux Ubuntu 安装gnirehtet Arch Linux可通过aur安装 Ubuntu 需要手动下载,访问https://github.com/Genymobile/gnirehtet/releases下载最新版,有java版和rust版,个人建议下载rust版的,rust版的解压后仅包含两个文件“gnirehtet”和“gnirehtet.apk”。 进入解压目录,手动安装(不是必须的,可以跳过) 手机进入开发者模式并打开USB调试 不同手机界面会有些区别,但都差不多,设置里找到系统版本号连点7下,会提示进入开发者模式,之后再找到“开发者选项”,打开USB调试即可(也有叫Android调试的) 连接电脑 插入数据线将手机连接到电脑,手机会有弹窗“允许USB调试吗?”,点击允许(有的手机不会弹窗,默认仅充电,可以在通知栏修改连接选项) 可通过命令查看是否已连接 运行 注意:如果你的手机有其他VPN软件并且该VPN设置了“始终开启的VPN”选项,请先关闭,否则即使连接了“Gnirehtet”也可能中途断开无法上网 执行以下命令,会自动检测、安装“gnirehtet.apk”到手机、添加VPN(手机会弹出提示,需要确认)并转发手机网络数据 要停止的话,电脑上直接“Ctrl + C”就行 抓包 wireshark找不到网卡无法抓包解决方法:linux下wireshark无法抓包问题 wireshark抓电脑有线网卡的包即可。由于这种共享网络的方式没有使用额外网口,只能抓电脑出口网卡的报文,手机产生的报文会和电脑本身发送/接收的报文混在一起,算是个缺点 可选:添加gnirehtet快捷启动方式(Desktop entries) 在“~/.local/share/applications/”添加一个desktop文件,让桌面环境菜单能够找到并添加该程序(当然这个desktop文件可以放到任何目录,比如桌面,双击即可运行) 更新数据库 参考:
图片来源:https://www.pixiv.net/artworks/96346431 配置了v2ray+cgproxy的透明代理,每次v2ray更新之后都会失效,需要手动添加抓包相关权限,通过添加hook的方式在更新后自动添加权限 备注:Type使用Path而不使用package是因为官方仓库、archlinuxcn以及aur中都有v2ray安装包,Path更通用一些;Target使用“usr/bin/v2ray”而不是“/usr/bin/v2ray”,否则匹配不上 参考:
图片来源:https://www.pixiv.net/artworks/72641025 Meyer’s Singleton 利用C++11保证静态局部变量初始化线程安全的特性 或许有用的模板实现 相对灵活,能够返回任意类型的固定对象指针,通过重载运算符略微增加复制语句的复杂度,但并不能阻止类型本身对象的复制 可以像这样复制T类型对象内容 参考:
图片来源:https://www.pixiv.net/artworks/101597578 大端序(网络序):高字节在低地址 小端序:高字节在高地址 判断当前运行环境的字节序 C++ 通过自定义变量值判断 另外,C++标准中对于结构体的非活跃成员的访问属于未定义行为,虽然使用g++编译运行都没问题,但以下代码不能保证运行结果正确 使用GCC宏 C++20标准库已经内置了字节序相关变量 Shell 输出“1”则为小端序,输出“0”则为大端序 查看CPU参数 CPU相关信息里的“Byte Order”字段有字节序信息 转换 Linux函数 Shell 反转字节序,输入输出均为十进制数 参考:
图片来源:https://www.pixiv.net/artworks/79954652 使用的设备是 OnePlus 7pro ,刷机和root步骤: Linux下给一加7Pro刷入LineageOS、获取root权限 破解软件下载网站 输入法 fcitx5-android ,使用体验和linux上的fcitx5感觉差不多,目前(2022/10/05)还在开发中,要尝鲜可以访问https://jenkins.fcitx-im.org/job/android/job/fcitx5-android/ 下载安装包,导入词典后已经是能用的状态了。虚拟键盘底部有一行多余按键,去除方法在下面 词典 到项目的release界面下载“.dict”文件 导入方法:小企鹅输入法5 -> 输入法 -> 拼音 -> 词典 -> 右下角+号 -> 选择刚刚下载的词典文件 Magisk模块 root文件编辑 推荐Root Explorer(RE管理器),配置magisk模块经常需要以root身份编辑文件 去除键盘底部多余部分 安装magisk模块HideNavBar 广告屏蔽模块——AdGuardHome_magisk 项目地址:https://github.com/410154425/AdGuardHome_magisk 这是一个让AdGuardHome运行在安卓设备上的去广告magisk模块,原理是拦截DNS请求,对应用开屏广告可能无效(应用开屏广告可安装使用Scene5的自动点击功能)。后台管理地址 http://127.0.0.1:3000 ,用户/密码都是root 通过修改 /data/adb/modules/AdGuardHome/mode.conf 可切换模式,内有相关说明 性能优化模块——Uperf 项目地址:https://github.com/yc9559/uperf 通过修改 /sdcard/Android/yc/uperf/cur_powermode.txt 可设置启动时的默认性能模式,可选的模式有: 安装Scene5 ,通过软件内的“调节”区块方便切换性能模式 存储空间隔离模块 官网:https://sr.rikka.app/zh-hans/ APP下载:酷安,GooglePlay magisk模块下载:https://github.com/RikkaApps/StorageRedirect-assets/releases 需要在magisk配置中开启Zygisk LSPosed 官方仓库:https://github.com/LSPosed/LSPosed APP下载:https://play.google.com/store/apps/details?id=org.lsposed.manager&hl=zh&gl=US magisk模块下载:https://github.com/LSPosed/LSPosed/releases 一些LSPosed模块 定位模拟 虽然magisk和LSPosed都有修改定位的模块,但功能都比较简单,相比之下fake location功能可说相当强大,包含位置模拟、路线模拟、wifi模拟等 AppOps LineageOS自带的权限管理不够细致,Scene5内置的权限管理还行,但不能按权限查看,目前用的权限狗基本能满足需求, 权限狗:酷安,GooglePlay 制作启动盘——DriveDroid DriveDroid 可以启动Linux镜像文件和WindowsPE,让手机变成PC系统急救工具
图片来源:《空之境界-未来福音》截图 解锁bootloader、刷机部分基本照抄的LineageOS官方教程,有基本的英语阅读能力的话建议直接看官方教程 工具 刷机要用到adb和fastboot, Arch Linux下安装“android-tools”即可 其他Linux发行版可以参考Linux查询文件所属包和查看包所包含文件,来查找adb和fastboot命令属于哪个包 进入开发者模式 设置->关于手机,连点7次版本号,成功会有“您现在处于开发者模式”的提示 打开USB调试 设置->系统->开发者选项,开启“USB调试” 解锁bootloader 解锁OEM 设置->系统->开发者选项,开启“OEM解锁” 连接到电脑 插入数据线连接到电脑,手机会有弹窗“允许USB调试吗?”,点击允许。可通过命令查看是否已连接 进入fastboot模式 或者也可以通过在关机状态下按住“音量+”+ “音量-” + “电源按键”直接启动进入fastboot模式 确认手机正常连接到fastboot 解锁 执行命令后手机会显示相关警告,通过音量键选择“UNLOCK THE BOOTLOADER”解锁,解锁会导致手机重启,如果没重启可以手动重启一次,确保能正常进入系统 刷机 刷入Lineage Recovery 访问https://download.lineageos.org/guacamole下载一加7Pro对应的Recovery镜像(img后缀) 参考“解锁bootloader”时的步骤进入fastboot模式,并确保连接正常 刷入Recovery 执行成功后在手机上用音量键选择到“Recovery mode”并按电源键进入Recovery模式。或者也可以在关机状态下按住“音量-”+ “电源键”启动并进入Recovery模式 进入Recovery模式后,执行电脑上执行“adb devices”确认是否正常连接,如果没有的话Recovery主菜单选择 Advanced->Enable ADB Ensuring all firmware partitions are consistent 没有相关知识,这部分没看懂,总之是解决潜在问题 访问https://mirrorbits.lineageos.org/tools/copy-partitions-20220613-signed.zip下载相关文件 进入 Apply Update->Apply from ADB ,执行: 返回Recovery主菜单,Advanced->Reboot to recovery 重启进入Recovery模式 刷入LineageOS 访问https://download.lineageos.org/guacamole下载一加7Pro对应的LineageOS镜像(zip后缀) 进入Recovery模式,格式化以去除磁盘加密,Factory reset->Format data / factory reset->Format data 返回Recovery主菜单,进入 Apply Update->Apply from ADB ,执行: 执行可能会卡在“47%”的进度,最后报错,属正常现象,其实刷成功了 如果不需要安装下面的google相关应用和获取root权限的话,这里直接回到Recovery主菜单,选择“Reboot system now”就完成了 如果卡在开机界面无法启动(正常第一次启动不会超过15分钟,我的1分钟左右就进入使用引导了),很有可能是漏了上面某个步骤,可以长按“音量+”+“电源键”10秒强制关机,然后重新进入fastboot或者recovery重新进行上面的步骤 Google Apps(可选) 官方用的是https://wiki.lineageos.org/gapps里的安装包(MindTheGapps 和 OpenGapps),包含一些我不需要的应用,这里选择BiTGApps保证最小化安装( Google Play Store和运行必要的服务) 访问https://bitgapps.github.io/download.html获取安装包(arm64,android11),进入Recovery模式(如果刷了LineageOS没重启过,返回Recovery主菜单,Advanced->Reboot to recovery 重启进入Recovery模式),进入Apply Update->Apply from ADB,执行: 由于BiTGApps没有使用LineageOS 的密钥签名,手机会弹出警告,选择yes即可,安装完成后重启手机即可 获取Root权限 通过刷入magisk来获取和管理root权限 访问https://magiskapp.com/apk/下载最新版magisk安装包(页面加载完成后,需要等待15秒左右才会出现“Download Magisk App (Latest)”按钮) 访问https://github.com/topjohnwu/magisk/releases下载最新版magisk安装包 手机正常开机,然后电脑上使用 adb 安装 magick 应用(或者也可以自己传到手机上像正常应用一样安装) 安装完成后打开Magisk应用,会提示“需要修复环境”,点击确认,之后会自动重启。 进入Recovery模式,进入Apply Update->Apply from ADB,电脑上还是使用刚才下载的安装包,将文件后缀由apk改为zip,执行: 由于magisk没有使用LineageOS 的密钥签名,手机会弹出警告,选择yes即可,安装完成后重启手机即可 如何卸载Magisk 打开手机上的Magisk应用,点击 卸载 Magisk->完全卸载,之后会自动重启进入Recovery模式。 Recovery模式下, 进入 Apply […]
图片来源:https://www.pixiv.net/artworks/81470216 预备知识 算术右移 算术右移会保留符号位(或者填充符号位),这样可以保证左移一位等于除以2 ,算术上符合直觉;但如果只是观察bit位变化,对于负数来说,算术右移看起来就是不断在左边填充“1”,和其他位移操作相比,显得不那么符合直觉(无符号数左移/右移、正数算术左移/右移、负数算术左移都可以理解为填充“0”)。 C++ 20 明确规定了对于有符号数的右移为算术右移,C++ 20 前虽没明确规定,但大多编译器的实现上也是算术右移: For negative a, the value of a >> b is implementation-defined (in most implementations, this performs arithmetic right shift, so that the result remains negative). (until C++20) The value of a >> b is a/2b, rounded down (in other words, right shift on signed a is arithmetic right shift). (since C++20) Arithmetic operators 隐式类型转换 C++ 算术运算符不接受小于“int”的类型,所以位移运算前会把 signed char 转换成 int ,unsigned char 转换成 unsigned int 。观察bit位变化,对于无符号数和有符号正数来说,转换后额外bit位填充的是“0” ,对于负数来说转换后额外bit位填充的是“1”。 循环位移模板实现(C++ 20) 参考:
图片来源:https://www.pixiv.net/artworks/58190158 其实添加一个函数在文章内容后面拼接版权声明代码就行,可以直接修改主题代码,但个人建议安装一个用于给WordPress加载额外代码的插件,方便管理,比如“Code Snippets” 安装并启用“Code Snippets”插件后,左边会多一个“Snippets”选项,点击“Snippets -> Add New”,进入编辑代码编辑界面。代码标题可以随便起,粘贴下面的PHP代码,然后滚动到页面最下方点击“Save Changes and Activate”即可 参考:
图片来源:https://www.pixiv.net/artworks/101295432 Linux下从网卡读取数据需要root权限,以普通用户身份运行的Wireshark无法抓包 临时方案 使用root权限启动Wireshark 不太安全的方案 利用“SUID”让所有用户执行特定二进制程序时能够拥有root权限,SUID简单介绍可参看 SUID、SGID和SBIT 推荐方案 给 /usr/bin/dumpcap 添加抓包的权限,添加一个新用户组wireshark,使所有组内用户能够执行 /usr/bin/dumpcap,有的Linux发行版(比如ArchLinux、Ubuntu)用包管理器安装wireshark后,其实默认就是这个方案,只是不会自动将用户加入wireshark用户组而已 查看/usr/bin/dumpcap 如果输出类似上面这样, 文件所属组为wireshark,组成员具有可读和可执行权限,则只需要将当前用户加入wireshark用户组,然后注销重新登录即可 如果不是话,就要自己手动执行创建用户组等全部操作,然后注销重新登录 参考:
图片来源:https://www.pixiv.net/artworks/100578118 C 取模 C语言的取模运算符(%)仅支持整数,定义如下: 对于 a/b , C语言会自动截断计算结果的小数部分, C99规定了”趋零截断”,举个例子 2.14 会截断为 2 , -2.14 会截断为 -2 。 简单来讲,C语言取模结果的符号(正数还是负数)与 a 的符号相同 Lua 取模 Lua取模操作有两种 % 和 math.fmod() ,稍微有一点区别: “//” 在lua中称为floor除法(floor division),会将运算结果向负无穷取整(rounds the quotient towards minus infinity),举个例子 2.14 会截断为 2.0 , -2.14 会截断为 -3.0。需要注意的两点: 参考: