算法 - 前缀和

在需要频繁地求数组中区间的和的情景下,前缀和数组十分有用。花费 $O(n)$ 的时间生成前缀和,之后只需要 $O(1)$ 的时间计算区间和。 定义一个数组a = [1, 2, 3, 4, 5],它的前缀和数组: prefix[0] = 1 prefix[1] = 1 + 2 = 3 prefix[2] = 1 + 2 + 3 = 6 prefix[3] = 1 + 2 + 3 + 4 = 10 prefix[4] = 1 + 2 + 3 + 4 + 5 = 15 要计算 $[i,j]$ 区间的和,可以用 prefix[j] - prefix[i-1] 算出,其中 i = 0 下溢时直接取 prefix[j]。 vector<int> prefix(n); int sum = 0; for(int i = 0; i < n; i++) { sum += i; prefix[i] = sum; } C++的numeric库提供了一个方便的函数partial_sum可以快速计算前缀和。 ...

May 4, 2025 · LingC

2025蓝桥杯赛后总结

这次省赛,实际上我并无准备,因为我一如既往地对算法没有什么兴趣。 竞赛一共八道题,A和B题是填空题,后六道题都是程序设计。前五题都做了,第六题暴力应该只拿了部分分,后两题就没时间写了。 在赛场上当时看到C++编译器是2014年发布的gcc 4.7.4,用的是C++98标准。但蓝桥杯的云端是可以运行C++11以上的标准的代码的。 本地做题环境的编译器低版本,导致许多C++函数用不了。比如 to_string()函数用不了。前两题最快速的做饭需要将数转到字符串类型,但是我只知道c++中有一个方便的 to_string() 函数,还好当时我看到赛场机子中有Pycharm,所以我就用python计算了前两道填空题。 这个向下兼容的过程,消耗了我大量时间。 最致命的是,有一道题我需要声明一个迭代器,但是我不知道迭代器的类型名,一般来说都是用auto自动推导的,但auto只在C++11标准以上才有,导致这道题的代码我在本地环境无法测试。明明代码是正确的,但本地的低版本编译器却认为我的代码是错误的。这种割裂感很少有。 而现在看来这道题也依旧做对了。 // C++98 std::vector<int> vec; std::vector<int>::iterator it = vec.begin(); // C++ 11 auto it = vec.begin(); // 自动推导为 std::vector<int>::iterator 与当时赛场的老师沟通,得知组委会只要求提供5.11版本的dev c++,而他们似乎只更新了代码编辑器版本,但一般来说dev c++是捆绑了一个编译器的,但不知为何内置的编译器却十分古典,感觉有点意思。 比赛完后,我查找了在 C++98 的字符串类型转换方法: // for C++98/03 standard string old_int_to_string(int v) { ostringstream oss; oss << v; return oss.str(); } string old_double_to_string(double v) { ostringstream oss; oss << fixed << setprecision(6) << v; return oss.str(); } string old_c_style_to_string(int v) { char buffer[32]; // make sure buffer is suffcient sprintf(buffer, "%d", v); return string(buffer); } 事实上,生活在草台班子里的我们不必认真太多。 ...

May 1, 2025 · LingC

JavaScript 逆向 Steam 登录二维码

众所周知,steam里骗子猖狂。以下页面是骗子私信发给我的一个仿冒的steam钓鱼网站。 如果点击 接受礼物 就会跳转至虚假的steam登录界面。 如果毫无防备,通过手机steam客户端扫描右边的二维码进行登录,steam会进行登录异常的警告,一般来说要通过这一步还是很麻烦的。如果强行继续,那么steam账号除了会被劫持api key以外,大概率还会被洗库存,比如一些便宜的卡片和库存里的小件都会被卖出,而不会触发steam手机令牌的验证。 那么骗子是如何制作这些钓鱼网站的?steam对于自身系统的保护究竟做的怎么样? 这些都绕不开对于steam的逆向分析。 开始逆向 抓包观察了一会steam登录界面后,就已经捋清了整个登录站点的逻辑。 在最开始会连接/BeginAuthStatusViaQRCode 获取登录二维码,之后每隔一段时间(5s)就会请求 PollAuthSessionStatus/v1 以更新会话状态,如果当前页面的二维码已经过期,则会刷新。 如果先点击登录按钮,会请求/GetPasswordRSAPublicKey/v1,之后是 /BeginAuthSessionStatusViaCredentials。 可以很明显的看到用的是 protobuf 协议。 查看这个网络请求的来源: 继续追踪这个API的来源。在js文件顶部可以看到这是用webpack打包的: 找到来自Send的方法调用比较可疑: 这里的 r 是一个对象,查看一下它的构造方法: 已经能看到proto的结构了。 构建出用于请求GetPasswordRSAPublicKey/v1的proto: syntax = "proto3"; package steam; option go_package = "proto/steam" message GetPasswordRSAPublicKey_Request { string account_name = 1; } message GetPasswordRSAPublicKey_Response { string public_key_mod = 1; string public_key_exp = 2; uint64 timestamp = 3; } 编译proto: $ protoc --go_out=. --go-grpc_out=. steam.proto 安装golang的protobuf包: ...

February 5, 2025 · LingC

快速求解平方根倒数算法

本文介绍了一种快速计算平方根倒数的算法,该算法源于上世纪90年代。文章首先解释了浮点数在计算机中的存储方式,特别是float32格式的结构,包括符号位、指数位和尾数位。接着,介绍了牛顿迭代法的基本原理及其在求解平方根倒数中的应用。通过对浮点数的对数变换,推导出与平方根倒数相关的公式,并解释了代码中使用的神秘常数 0x5f3759df 的来源,最后提到切比雪夫最佳逼近的概念,以优化计算结果。

February 4, 2025 · LingC

Protobuf

安装 protobuf 假设环境下已有protoc (protocal buffers compiler)。 对于 Go 语言,安装相应的可执行文件: go install google.golang.org/grpc/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 在Windows中,执行完安装命令后在C:\Users\user\go\bin路径下会有proctoc-gen-go.exe和protoc-gen-go-grpc.exe。 安装完Go插件后,我们希望protoc生成Go语言的代码,需要为 .proto 文件加一行以指定生成的Go包名: syntax = "proto3"; package com.example.pkg option go_package = "example/gopkg" 如果需要使用 grpc 服务,安装包: go get google.golang.org/grpc 之后便可启动一个 gRPC 服务器: gRPC gateway 为 gRPC 服务生成面向 RestFul API 的网关 go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest syntax = "proto3"; package com.example.pkg import "google/api/annotations.proto"; option go_package = "example/gopkg service AuthService { rpc Login(LRequest) returns (LResponse) { option (google.api.http) = { post: "/v1/login" body: "*" }; } message LRequest { string field = 1; } message LResponse { string field = 1; } 之后便可以生成grpc gateway的代码了: ...

January 24, 2025 · LingC

Android设备安装Debian成为BT下载服务器

文章介绍了如何在Android设备上通过Termux安装Debian,并配置VNC以便远程访问。作者提到,由于Android 12引入的Phantom Process Killer机制,Termux容易被杀死,因此提供了关闭该限制的ADB命令。接着,文章详细说明了如何安装XFCE桌面环境和配置VNC服务器,包括使用TightVNC的步骤。最后,作者提到可以进一步安装gogs作为本地Git服务器。

August 7, 2024 · LingC

[双系统] Windows 更新摧毁了我的Linux系统

在 Windows 更新后,用户的 Linux 系统因等待 90 秒而无法启动,并且出现依赖失败。调查发现,Windows 调换了 Linux 分区和恢复分区的顺序,从而导致了问题。用户通过修复 Linux、更新 fstab、重新安装 Grub 和使用 efibootmgr 更改启动顺序解决了问题。

August 3, 2024 · LingC

Golang embed 使用问题

Golang 使用 embed 包在编译时将外部文件包含到二进制程序中。使用 embed 指令可以将 html、css、js 等静态文件添加到二进制文件中,而无需额外的资源文件。嵌入文件可以使用字符串、[]字节和 FS 来引用。但也有一些限制,如文件层次结构问题和复杂路径问题。例如,如果嵌入文件和被嵌入文件不在同一层次,嵌入模式将无法成功解析。另一个问题是处理复杂路径,即静态文件夹被放置在嵌入文件的子文件夹中。解决办法是使用 io/fs 软件包中的 Sub 方法来处理这些复杂路径。

December 27, 2023 · LingC

Hexo博客自动备份插件 云盘备份支持

本文讨论了博客数据备份方案,强调321原则:保留3个备份副本,使用2种不同储存介质,1个备份远离数据源。最初考虑使用GitHub Action进行备份,但发现其局限性。为此,开发了Hexo插件“hexo-auto-backup”,可在执行hexo deploy时自动备份重要文件到本地或云盘,支持多种云服务和协议。插件安装简单,通过npm安装。未来计划改进备份过期设置和多系统支持。详细信息可见插件的GitHub仓库。

December 19, 2023 · LingC

通过汇编分析栈、函数调用 esp&ebp

栈是一种遵循后进先出(LIFO)规则的数据结构,通常用于内存管理。重要寄存器包括栈指针(SP)和基指针(BP)。在函数调用中,使用push将参数压入栈中,call指令保存返回地址。ESP寄存器指向栈顶,函数执行后需平衡栈。C语言函数调用中,参数通过EBP寻址,编译器可能使用mov而非push,使得ESP不指向栈顶,简化栈平衡的处理。

December 15, 2023 · LingC