post on 15 Apr 2025 about 7031words require 24min
CC BY 4.0 (除特别声明或转载文章外)
如果这篇博客帮助到你,可以请我喝一杯咖啡~
飞书文档链接 1.1.二进制思想在计算机科学中的应用
二进制是一种基数为 2 的数制,只使用两个数字——0 和 1。这两个数字被称为比特(bit),是计算机中最小的数据单位。二进制是计算机科学的基础,用于表示所有数据类型。例如,文本通过 ASCII 编码转为二进制,图像和声音也以二进制存储。逻辑电路依赖二进制逻辑门(如 AND、OR、NOT)执行计算,处理器通过二进制指令执行操作。此外,二进制在数字通信、加密技术和错误检测中也至关重要。这些应用确保了现代计算系统的功能。
密码学的所有技术实现均基于二进制运算,二进制是计算机处理数据的基础单位,密码学通过二进制操作实现数据的加密、哈希、签名等核心功能。
示例:AES 加密中的“字节替换(SubBytes)”步骤,本质是二进制字节通过 S 盒(查找表)进行非线性变换。
大整数运算
示例:RSA 加密中,公钥加密过程本质是计算 $C = M^e \mod n$,其中 $ M, e, n $ 均为二进制大整数。
二进制优化
因此,可以将$e$写成:
\[e = 2^3 + 2^2 + 2^0\]然后分别计算 $2^3$、$2^2$以及 $2^0 $ 与求和即可
密钥生成
密钥存储
网络协议
编码与解码
- 基于二进制的权限管理与验证 - 勤奋的菜鸟 - 博客园
[权限控制 使用二进制做权限控制功能](https://www.zhihu.com/column/p/30103832)
Linux 中每个文件/目录的权限分为 所有者(User)、所属组(Group)、其他用户(Others) 三个角色,每个角色对应 读(r)、写(w)、执行(x) 三种权限,分别用 3 位二进制 表示:
1
2
3
rwx r-x r-- → 二进制:111 101 100 → 八进制:754
↑ ↑ ↑
用户 组 其他
• 每个权限位映射:
• r
(读):二进制第 2 位(值 4)
• w
(写):二进制第 1 位(值 2)
• x
(执行):二进制第 0 位(值 1)
• 权限组合:通过二进制位或运算(|
)实现,例如:
1
2
rw- = 4(r) + 2(w) = 6 → 二进制 110
rwx = 4 + 2 + 1 = 7 → 二进制 111
权限验证
Linux 内核通过 按位与运算(&) 判断用户是否拥有某权限。例如,检查用户是否有执行权限:
1
2
// 检查 st_mode 是否包含用户执行权限位
if (st_mode & S_IXUSR) { /* 允许执行 */ }
• 权限位宏定义:
1
2
3
#define S_IRUSR 0400 // 用户读权限(二进制:100 000 000)
#define S_IWUSR 0200 // 用户写权限(二进制:010 000 000)
#define S_IXUSR 0100 // 用户执行权限(二进制:001 000 000)
通过 **按位或( | )赋予权限** 和 按位与非(& ~)移除权限 实现动态调整: |
1
2
3
4
5
// 添加用户写权限
st_mode |= S_IWUSR;
// 移除用户执行权限
st_mode &= ~S_IXUSR;
• 符号模式:直接操作权限位
1
2
chmod u+x file # 添加用户执行权限(位或运算)
chmod g-w file # 移除组写权限(位与非运算)
• 八进制模式:直接指定二进制掩码
1
chmod 755 file # rwxr-xr-x → 二进制 111 101 101 → 八进制 755
• umask 值:通过二进制掩码定义默认权限的补码
1
umask 022 # 默认创建文件权限为 644(777 & ~022 = 755)
Linux 还扩展了 SUID、SGID、Sticky Bit 等权限,仍基于二进制位掩码设计:
• SUID(Set User ID):二进制第 11 位(八进制 4000)
1
chmod u+s /usr/bin/passwd # 设置SUID,允许普通用户以root权限修改密码
• Sticky Bit:二进制第 9 位(八进制 1000)
1
chmod +t /tmp # 仅文件所有者可删除自己的文件
|
、&
、~
)实现动态调整。这一设计充分体现了二进制在权限控制中的核心价值——简洁、高效、灵活。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;
const int S_IXUSR = 0400;_ // 用户读权限(二进制:100 000 000)_
const int S_IWUSR = 0200;_ // 用户写权限(二进制:010 000 000)_
const int S_IXUSR = 0100;_ // 用户执行权限(二进制:001 000 000)_
void check_permission(int st_mode)
{
_ // 检查 st_mode 是否包含用户执行权限位_
if (st_mode & S_IXUSR)
{
_ /* 允许执行 */_
}
}
在计算机中,带符号整数通常用 补码 表示,其转换流程为:
值 | 原码(二进制) | 反码 | 补码 |
+5 | 00000101 | — | 00000101 |
–5 | 10000101 | 11111010 | 11111011 |
补码的好处是:加减运算都能统一为加法,省去了符号位处理的特殊逻辑,也天然支持异或、与或等位运算。
~x
将 x 的每一位二进制翻转。x & y
,常用于屏蔽某些位,比如 x & 1
可判断 x 的奇偶。x \| y
,用于将某些位设为 1。x ^ y
,相同位结果为 0,不同位结果为 1。例如,下面函数高效判断一个整数是否是 2 的幂次方:
1
2
3
bool isPowerOfTwo(int x) {
return x > 0 && (x & (x - 1)) == 0;
}
1
2
def is_power_of_two(x: int) -> bool:
return x > 0 and (x & (x - 1)) == 0
\[e = 1 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0\]
- 快速幂模运算通过二进制分解指数(如 $e = 2^k + 2^{k-1} + … $)加速计算。 假设指数$e$是一个正整数,它可以表示为二进制形式。例如,假设 $e = 13$,其二进制表示为 $1101_2$。这意味着:
因此,可以将$e$写成:
\[e = 2^3 + 2^2 + 2^0\]然后分别计算 $2^3$、$2^2$以及 $2^0 $ 与求和即可
算法思想:
res=1
;res *= a
;a *= a
(平方),并将 $e$ 右移一位;res
即为 $a^e$。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
long long fast_pow(long long a, long long e) {
long long res = 1;
while (e > 0) {
if (e & 1) // 若当前最低位为 1
res = res * a;
a = a * a; // 平方
e >>= 1; // 右移下一位
}
return res;
}
int main() {
std::cout << fast_pow(2, 13) << std::endl; // 输出 8192
return 0;
}
1
a ^= b; b ^= a; a ^= b;
对于一个数组中只有一个元素出现一次,其余元素都出现两次,用异或可线性时间、常数空间找出它:
1
2
3
4
5
def single_number(nums):
ans = 0
for x in nums:
ans ^= x
return ans
将 n
的第 i
到 j
位全部翻转:
1
2
int mask = ((1 << (j - i + 1)) - 1) << i;
n ^= mask;
数据压缩可以分为有损压缩(Lossy)和无损压缩(Lossless)两类。
1
2
3
4
5
6
7
8
9
import gzip
text = b"Data compression example. " * 100
# 压缩
compressed = gzip.compress(text)
print("原始大小:", len(text), "压缩后大小:", len(compressed))
# 解压
decompressed = gzip.decompress(compressed)
assert decompressed == text
以上示例使用 DEFLATE 算法,无损地将文本压缩并恢复
1
2
3
from PIL import Image
img = Image.open("input.png")
img.save("output.jpg", quality=50) # quality<100 会丢失部分细节
1
2
# 对比文件体积
ls -lh input.jpg output.jpg
通过调整 quality
参数,JPEG 有损压缩可在保留较好视觉效果的同时大幅减小文件体积。
https://colab.research.google.com/drive/1VpmC-vKrvaFusdNNuaavzvAk2YMhGWrW?usp=sharing(colab 链接)
One-Hot 编码是一种将分类变量转换为稀疏二进制向量的技术,每个类别对应一个维度,只有所属类别位置为 1,其它位置为 0。
1
2
3
4
import pandas as pd
df = pd.DataFrame({"color": ["red", "blue", "green", "blue"]})
one_hot = pd.get_dummies(df["color"], prefix="color")
print(one_hot)
1
2
3
4
5
color_blue color_green color_red
0 False False True
1 True False False
2 False True False
3 True False False
此方法对小规模类别集非常高效,并集成于 Pandas。
1
2
3
4
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(sparse=False)
X = enc.fit_transform(df[["color"]])
print(X)
1
2
3
4
[[0. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]
[1. 0. 0.]]
OneHotEncoder
支持 handle_unknown
参数,用于处理训练外出现的新类别。
深度学习框架通常使用专门的二进制格式保存模型参数和网络结构,以提高读写性能并节省存储空间。
.pt
或 .pth
文件,通常调用 torch.save(model.state_dict(), 'model.pth')
和 model.load_state_dict(torch.load('model.pth'))
。saved_model.pb
(Protobuf 二进制)与 variables
检查点文件,使用 model.save('path')
和 tf.keras.models.load_model('path')
进行读写。1
2
import safetensors.torch as st
st.save_file(model.state_dict(), "model.safetensors")
此外,ONNX(Open Neural Network Exchange)以 Protobuf 二进制保存跨框架模型结构与权重,易于在不同平台间互操作。
在前端设计中,颜色可通过多种编码表示,最常见的是 十六进制(Hex)、RGB(A) 与 HSL(A) 格式。
#RRGGBB
或简写 #RGB
,例如 #ff00aa
。rgb(255,0,170)
,可加透明度:rgba(255,0,170,0.5)
。hsl(320,100%,50%)
,直观调节色相、饱和度、亮度。CSS 示例:
1
2
3
4
5
.button {
background: #3498db; /* Hex */
color: rgb(255, 255, 255); /* RGB */
border-color: hsl(200, 70%, 50%); /* HSL */
}
JavaScript 转换示例:
1
2
3
4
5
6
7
8
9
10
11
// Hex to RGB
function hexToRgb(hex) {
let m = hex.match(/^#?([A-F\d]{2})([A-F\d]{2})([A-F\d]{2})$/i);
if (!m) return null;
return {
r: parseInt(m[1], 16),
g: parseInt(m[2], 16),
b: parseInt(m[3], 16)
};
}
console.log(hexToRgb("#ff00aa")); // {r:255, g:0, b:170}
计算机网络(一)基本概念(IP,子网掩码,默认网关,DNS) 【计算机网络】IP 协议、IP 地址、网段划分、子网划分、子网掩码、CIDR_ip cidr-CSDN 博客 IP 地址、子网掩码、网关、DNS 之间的关系
IP 地址、子网掩码、默认网关与 DNS 协同完成局域网与互联网互联:
192.168.1.10/24
。255.255.255.0
(/24),用于划分网络号与主机号。192.168.1.1
。8.8.8.8
)。1
2
3
4
5
6
import ipaddress
net = ipaddress.ip_network("192.168.1.10/24", strict=False)
print("网络地址:", net.network_address)
print("广播地址:", net.broadcast_address)
print("可用主机:", list(net.hosts())[:3], "…共", net.num_addresses - 2)
Related posts