gaskill 2.17.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. gaskill-2.17.0/LICENSE +21 -0
  2. gaskill-2.17.0/PKG-INFO +43 -0
  3. gaskill-2.17.0/README.md +16 -0
  4. gaskill-2.17.0/gaskill/__init__.py +13 -0
  5. gaskill-2.17.0/gaskill/gaskill/__init__.py +28 -0
  6. gaskill-2.17.0/gaskill/gaskill/_roll.py +169 -0
  7. gaskill-2.17.0/gaskill/gaskill/abc.py +73 -0
  8. gaskill-2.17.0/gaskill/gaskill/hashlib.py +186 -0
  9. gaskill-2.17.0/gaskill/gaskill/pickle.py +318 -0
  10. gaskill-2.17.0/gaskill/gaskill/sbase64.py +287 -0
  11. gaskill-2.17.0/gaskill/gaskill/scache.py +448 -0
  12. gaskill-2.17.0/gaskill/gaskill/scolor.py +388 -0
  13. gaskill-2.17.0/gaskill/gaskill/scrypt.py +209 -0
  14. gaskill-2.17.0/gaskill/gaskill/scurve.py +387 -0
  15. gaskill-2.17.0/gaskill/gaskill/seasing.py +259 -0
  16. gaskill-2.17.0/gaskill/gaskill/sevent.py +218 -0
  17. gaskill-2.17.0/gaskill/gaskill/sformat.py +591 -0
  18. gaskill-2.17.0/gaskill/gaskill/sfrac.py +403 -0
  19. gaskill-2.17.0/gaskill/gaskill/sfsm.py +209 -0
  20. gaskill-2.17.0/gaskill/gaskill/sgeometry.py +790 -0
  21. gaskill-2.17.0/gaskill/gaskill/sgeometry3d.py +371 -0
  22. gaskill-2.17.0/gaskill/gaskill/sinterp.py +168 -0
  23. gaskill-2.17.0/gaskill/gaskill/smath.py +1111 -0
  24. gaskill-2.17.0/gaskill/gaskill/smatrix.py +605 -0
  25. gaskill-2.17.0/gaskill/gaskill/snoise.py +305 -0
  26. gaskill-2.17.0/gaskill/gaskill/solver.py +176 -0
  27. gaskill-2.17.0/gaskill/gaskill/spathfinder.py +547 -0
  28. gaskill-2.17.0/gaskill/gaskill/spool.py +201 -0
  29. gaskill-2.17.0/gaskill/gaskill/squaternion.py +439 -0
  30. gaskill-2.17.0/gaskill/gaskill/srandom.py +282 -0
  31. gaskill-2.17.0/gaskill/gaskill/ssaver.py +303 -0
  32. gaskill-2.17.0/gaskill/gaskill/sstat.py +463 -0
  33. gaskill-2.17.0/gaskill/gaskill/svector.py +756 -0
  34. gaskill-2.17.0/gaskill/gaskill/type.py +133 -0
  35. gaskill-2.17.0/gaskill/plus/__init__.py +11 -0
  36. gaskill-2.17.0/gaskill/plus/bmp.py +436 -0
  37. gaskill-2.17.0/gaskill/plus/database.py +177 -0
  38. gaskill-2.17.0/gaskill/plus/decimal.py +585 -0
  39. gaskill-2.17.0/gaskill/plus/ecc.py +160 -0
  40. gaskill-2.17.0/gaskill/plus/poly.py +426 -0
  41. gaskill-2.17.0/gaskill/plus/radical.py +608 -0
  42. gaskill-2.17.0/gaskill/plus/re.py +511 -0
  43. gaskill-2.17.0/gaskill/plus/sui.py +474 -0
  44. gaskill-2.17.0/gaskill/plus/tester.py +500 -0
  45. gaskill-2.17.0/gaskill/plus/zip.py +233 -0
  46. gaskill-2.17.0/gaskill/test/__init__.py +6 -0
  47. gaskill-2.17.0/gaskill/test/test_all.py +11 -0
  48. gaskill-2.17.0/gaskill/test/test_decimal.py +678 -0
  49. gaskill-2.17.0/gaskill/test/test_frac.py +487 -0
  50. gaskill-2.17.0/gaskill/test/test_radical.py +243 -0
  51. gaskill-2.17.0/gaskill/test/test_saver.py +152 -0
  52. gaskill-2.17.0/gaskill/test/test_smath.py +321 -0
  53. gaskill-2.17.0/gaskill.egg-info/PKG-INFO +43 -0
  54. gaskill-2.17.0/gaskill.egg-info/SOURCES.txt +56 -0
  55. gaskill-2.17.0/gaskill.egg-info/dependency_links.txt +1 -0
  56. gaskill-2.17.0/gaskill.egg-info/top_level.txt +1 -0
  57. gaskill-2.17.0/setup.cfg +4 -0
  58. gaskill-2.17.0/setup.py +60 -0
gaskill-2.17.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 limo1027
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: gaskill
3
+ Version: 2.17.0
4
+ Summary: A comprehensive Python library for game development utilities
5
+ Home-page: https://github.com/limo1027/gaskill
6
+ Author: Limo
7
+ Author-email: 28009663@qq.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.6
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license-file
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # Mlib
29
+ 一个0依赖库
30
+
31
+ 不依赖random,math等标准库
32
+
33
+ 纯python制作,不使用C拓展
34
+
35
+ 快速开始
36
+
37
+ ```bash
38
+ git clone https://github.com/limo1027/mlib
39
+ cd mlib
40
+ python -c "from gaskill.test import run_test; run_test()"
41
+ ```
42
+
43
+ [Learn More?](https://limo1027.github.io/mlib)
@@ -0,0 +1,16 @@
1
+ # Mlib
2
+ 一个0依赖库
3
+
4
+ 不依赖random,math等标准库
5
+
6
+ 纯python制作,不使用C拓展
7
+
8
+ 快速开始
9
+
10
+ ```bash
11
+ git clone https://github.com/limo1027/mlib
12
+ cd mlib
13
+ python -c "from gaskill.test import run_test; run_test()"
14
+ ```
15
+
16
+ [Learn More?](https://limo1027.github.io/mlib)
@@ -0,0 +1,13 @@
1
+ # ruff: noqa: F403
2
+ from .gaskill import *
3
+ from .plus import *
4
+ print(r"""
5
+ _ _ _
6
+ _ __ ___ | (_) |__
7
+ | '_ ` _ \| | | '_ \
8
+ | | | | | | | | |_) |
9
+ |_| |_| |_|_|_|_.__/ """)
10
+ print("Hello from mlib. It isn't a serious library. Welcome to raise PRs. If you want to know the rules, please see PRlicense.")
11
+ __PRlicense__ = "Do not use any C or Rust extensions, and ensure neither exists in the dependency tree."
12
+ __license__ = "MIT"
13
+ __author__ = "everyone"
@@ -0,0 +1,28 @@
1
+ # ruff: noqa: F403
2
+ from .smath import *
3
+ from .sfrac import *
4
+ from .svector import *
5
+ from .smatrix import *
6
+ from .squaternion import *
7
+ from .srandom import *
8
+ from .scolor import *
9
+ from .sgeometry import *
10
+ from .sgeometry3d import *
11
+ from .scurve import *
12
+ from .seasing import *
13
+ from .sinterp import *
14
+ from .scache import *
15
+ from .sevent import *
16
+ from .sfsm import *
17
+ from .spool import *
18
+ from .spathfinder import *
19
+ from .ssaver import *
20
+ from .sformat import *
21
+ from .snoise import *
22
+ from .scrypt import *
23
+ from .solver import *
24
+ from .sstat import *
25
+ from .sbase64 import *
26
+ from .abc import *
27
+ from .pickle import *
28
+ from .hashlib import sha256, DJB2 # noqa: F401
@@ -0,0 +1,169 @@
1
+ def parse_dice(expr):
2
+ expr = expr.replace(' ', '')
3
+
4
+ # 按加减号分割表达式
5
+ parts = _split_expression(expr)
6
+
7
+ result = {
8
+ 'expr': expr,
9
+ 'parts': [],
10
+ 'total': 0
11
+ }
12
+
13
+ for part in parts:
14
+ if 'd' in part.lower():
15
+ part_result = _parse_single_dice(part)
16
+ else:
17
+ part_result = _parse_number(part)
18
+
19
+ result['parts'].append(part_result)
20
+ result['total'] += part_result['value']
21
+
22
+ return result
23
+
24
+
25
+ def _split_expression(expr):
26
+ parts = []
27
+ current = ''
28
+
29
+ for i, char in enumerate(expr):
30
+ if char in '+-' and i > 0:
31
+ parts.append(current)
32
+ current = char
33
+ else:
34
+ current += char
35
+
36
+ if current:
37
+ parts.append(current)
38
+
39
+ return parts
40
+
41
+
42
+ def _parse_single_dice(expr):
43
+ d_pos = expr.lower().find('d')
44
+
45
+ # 解析骰子数量
46
+ count_str = expr[:d_pos]
47
+ count = int(count_str) if count_str else 1
48
+
49
+ # 解析剩余部分
50
+ rest = expr[d_pos+1:]
51
+
52
+ # 初始化结果
53
+ result = {
54
+ 'expr': expr,
55
+ 'type': 'dice',
56
+ 'count': count,
57
+ 'sides': 0,
58
+ 'modifier': None,
59
+ 'modifier_value': 0,
60
+ 'explode': None,
61
+ 'bonus': 0,
62
+ 'value': 0 # 占位,实际掷骰时计算
63
+ }
64
+
65
+ i = 0
66
+ # 读骰子面数
67
+ sides_str = ''
68
+ while i < len(rest) and rest[i].isdigit():
69
+ sides_str += rest[i]
70
+ i += 1
71
+
72
+ result['sides'] = int(sides_str)
73
+
74
+ # 读修饰符
75
+ if i < len(rest) and rest[i].isalpha():
76
+ mod = rest[i]
77
+ i += 1
78
+ if i < len(rest) and rest[i].isalpha():
79
+ mod += rest[i]
80
+ i += 1
81
+ result['modifier'] = mod
82
+
83
+ # 读修饰符数值
84
+ mod_val_str = ''
85
+ while i < len(rest) and rest[i].isdigit():
86
+ mod_val_str += rest[i]
87
+ i += 1
88
+ result['modifier_value'] = int(mod_val_str) if mod_val_str else 1
89
+
90
+ # 读爆炸骰
91
+ if i < len(rest) and rest[i] == 'x':
92
+ i += 1
93
+ explode_str = ''
94
+ while i < len(rest) and rest[i].isdigit():
95
+ explode_str += rest[i]
96
+ i += 1
97
+ result['explode'] = int(explode_str)
98
+
99
+ # 读加减
100
+ if i < len(rest) and rest[i] in '+-':
101
+ result['bonus'] = int(rest[i:])
102
+
103
+ return result
104
+
105
+
106
+ def _parse_number(expr):
107
+ return {
108
+ 'expr': expr,
109
+ 'type': 'number',
110
+ 'value': int(expr)
111
+ }
112
+
113
+
114
+ def roll_dice(parse_result, random_func):
115
+ if parse_result['type'] == 'number':
116
+ return parse_result['value']
117
+
118
+ # 先掷出所有骰子
119
+ rolls = [random_func(1, parse_result['sides'])
120
+ for _ in range(parse_result['count'])]
121
+
122
+ # 应用爆炸骰
123
+ if parse_result['explode']:
124
+ rolls = _apply_explode(rolls, parse_result['sides'],
125
+ parse_result['explode'], random_func)
126
+
127
+ # 应用修饰符
128
+ if parse_result['modifier'] == 'kh':
129
+ rolls = sorted(rolls, reverse=True)[:parse_result['modifier_value']]
130
+ elif parse_result['modifier'] == 'kl':
131
+ rolls = sorted(rolls)[:parse_result['modifier_value']]
132
+ elif parse_result['modifier'] == 'd':
133
+ rolls = sorted(rolls)[parse_result['modifier_value']:]
134
+
135
+ return sum(rolls) + parse_result['bonus']
136
+
137
+
138
+ def _apply_explode(rolls, sides, target, random_func):
139
+ """递归应用爆炸骰"""
140
+ result = rolls.copy()
141
+ for roll in rolls:
142
+ if roll == target:
143
+ extra = random_func(1, sides)
144
+ result.append(extra)
145
+ if extra == target: # 递归爆炸
146
+ result.extend(_apply_explode([extra], sides, target, random_func))
147
+ return result
148
+
149
+
150
+ def get_dice_info(expr):
151
+ result = parse_dice(expr)
152
+ info = {
153
+ 'expr': expr,
154
+ 'dice_count': 0,
155
+ 'total_sides': 0,
156
+ 'has_modifier': False,
157
+ 'has_explode': False
158
+ }
159
+
160
+ for part in result['parts']:
161
+ if part['type'] == 'dice':
162
+ info['dice_count'] += part['count']
163
+ info['total_sides'] += part['sides'] * part['count']
164
+ if part['modifier']:
165
+ info['has_modifier'] = True
166
+ if part['explode']:
167
+ info['has_explode'] = True
168
+
169
+ return info
@@ -0,0 +1,73 @@
1
+ """
2
+ gaskill.abc - 抽象基类模块(零依赖)
3
+ """
4
+
5
+
6
+ class ABCMeta(type):
7
+ """元类:自动收集抽象方法"""
8
+
9
+ def __new__(cls, name, bases, dct):
10
+ # 1. 从所有父类继承抽象方法
11
+ abstract_methods = set()
12
+ for base in bases:
13
+ if hasattr(base, '_abstract_methods'):
14
+ abstract_methods.update(base._abstract_methods)
15
+
16
+ # 2. 处理当前类定义的方法
17
+ for key, value in dct.items():
18
+ # 如果当前类显式定义了抽象方法(有 _is_abstract 标记)
19
+ if hasattr(value, '_is_abstract') and value._is_abstract:
20
+ abstract_methods.add(key)
21
+ else:
22
+ # 如果当前类定义了具体实现(没有 _is_abstract 标记)
23
+ # 并且该方法在抽象方法集合中,则移除(即实现了该抽象方法)
24
+ if key in abstract_methods:
25
+ abstract_methods.remove(key)
26
+
27
+ # 3. 存储最终的抽象方法集合
28
+ dct['_abstract_methods'] = frozenset(abstract_methods)
29
+ return super().__new__(cls, name, bases, dct)
30
+
31
+ def __call__(cls, *args, **kwargs):
32
+ """实例化时检查抽象方法是否都已实现"""
33
+ if cls._abstract_methods:
34
+ methods = ', '.join(cls._abstract_methods)
35
+ raise TypeError(
36
+ f"Can't instantiate abstract class {cls.__name__} "
37
+ f"with abstract methods {methods}"
38
+ )
39
+ return super().__call__(*args, **kwargs)
40
+
41
+
42
+ class ABC(metaclass=ABCMeta):
43
+ """抽象基类"""
44
+
45
+ def __init__(self):
46
+
47
+ if type(self) is ABC:
48
+ raise TypeError(
49
+ "Can't instantiate abstract class ABC with abstract methods")
50
+
51
+
52
+ def abstractmethod(func):
53
+ """装饰器:标记抽象方法"""
54
+ func._is_abstract = True
55
+ return func
56
+
57
+
58
+ def abstractclassmethod(func):
59
+ """装饰器:标记抽象类方法"""
60
+ func._is_abstract = True
61
+ return classmethod(func)
62
+
63
+
64
+ def abstractstaticmethod(func):
65
+ """装饰器:标记抽象静态方法"""
66
+ func._is_abstract = True
67
+ return staticmethod(func)
68
+
69
+
70
+ def abstractproperty(func):
71
+ """装饰器:标记抽象属性"""
72
+ func._is_abstract = True
73
+ return property(func)
@@ -0,0 +1,186 @@
1
+
2
+ H0 = 0x6a09e667
3
+ H1 = 0xbb67ae85
4
+ H2 = 0x3c6ef372
5
+ H3 = 0xa54ff53a
6
+ H4 = 0x510e527f
7
+ H5 = 0x9b05688c
8
+ H6 = 0x1f83d9ab
9
+ H7 = 0x5be0cd19
10
+
11
+ K = [
12
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
13
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
14
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
15
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
16
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
17
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
18
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
19
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
20
+ ]
21
+
22
+
23
+ def rotr(x, n):
24
+ """循环右移 n 位(32-bit)"""
25
+ return (x >> n) | ((x & ((1 << n) - 1)) << (32 - n))
26
+
27
+
28
+ def shr(x, n):
29
+ """逻辑右移 n 位(高位补 0)"""
30
+ return x >> n
31
+
32
+
33
+ def xor3(a, b, c):
34
+ """三个数的异或"""
35
+ return a ^ b ^ c
36
+
37
+
38
+ def add_mod32(a, b):
39
+ """32-bit 加法(自动截断)"""
40
+ return (a + b) & 0xffffffff
41
+
42
+
43
+ def ch(x, y, z):
44
+ """Choose: 根据 x 的位选择 y 或 z"""
45
+ return (x & y) ^ ((~x) & z)
46
+
47
+
48
+ def maj(x, y, z):
49
+ """Majority: 按位多数投票"""
50
+ return (x & y) ^ (x & z) ^ (y & z)
51
+
52
+
53
+ def sigma0(x):
54
+ """Σ0:用于压缩函数"""
55
+ return xor3(rotr(x, 2), rotr(x, 13), rotr(x, 22))
56
+
57
+
58
+ def sigma1(x):
59
+ """Σ1:用于压缩函数"""
60
+ return xor3(rotr(x, 6), rotr(x, 11), rotr(x, 25))
61
+
62
+
63
+ def gamma0(x):
64
+ """σ0:用于消息调度"""
65
+ return xor3(rotr(x, 7), rotr(x, 18), shr(x, 3))
66
+
67
+
68
+ def gamma1(x):
69
+ """σ1:用于消息调度"""
70
+ return xor3(rotr(x, 17), rotr(x, 19), shr(x, 10))
71
+
72
+
73
+ def pad_message(msg_bytes):
74
+ """
75
+ 将字节消息填充为 512-bit 整数倍
76
+ 返回:填充后的字节数组(每个元素 0-255)
77
+ """
78
+ msg_len = len(msg_bytes)
79
+ bit_len = msg_len * 8
80
+
81
+ padded = list(msg_bytes)
82
+
83
+ padded.append(0x80)
84
+
85
+ while len(padded) % 64 != 56:
86
+ padded.append(0x00)
87
+
88
+ for i in range(7, -1, -1):
89
+ padded.append((bit_len >> (8 * i)) & 0xff)
90
+
91
+ return padded
92
+
93
+
94
+ def bytes_to_words(block):
95
+ """block: 64 字节的 list,返回 16 个 32-bit 整数"""
96
+ words = []
97
+ for i in range(0, 64, 4):
98
+ w = (block[i] << 24) | (block[i+1] <<
99
+ 16) | (block[i+2] << 8) | block[i+3]
100
+ words.append(w)
101
+ return words
102
+
103
+
104
+ def compress_block(block_bytes, h_vals):
105
+ w = bytes_to_words(block_bytes)
106
+
107
+ for t in range(16, 64):
108
+ w.append(
109
+ add_mod32(
110
+ add_mod32(gamma1(w[t-2]), w[t-7]),
111
+ add_mod32(gamma0(w[t-15]), w[t-16])
112
+ )
113
+ )
114
+
115
+ a, b, c, d = h_vals[0], h_vals[1], h_vals[2], h_vals[3]
116
+ e, f, g, h = h_vals[4], h_vals[5], h_vals[6], h_vals[7]
117
+
118
+ for t in range(64):
119
+ t1 = add_mod32(
120
+ add_mod32(
121
+ add_mod32(
122
+ add_mod32(h, sigma1(e)),
123
+ ch(e, f, g)
124
+ ),
125
+ K[t]
126
+ ),
127
+ w[t]
128
+ )
129
+ t2 = add_mod32(sigma0(a), maj(a, b, c))
130
+
131
+ h = g
132
+ g = f
133
+ f = e
134
+ e = add_mod32(d, t1)
135
+ d = c
136
+ c = b
137
+ b = a
138
+ a = add_mod32(t1, t2)
139
+
140
+ return [
141
+ add_mod32(h_vals[0], a),
142
+ add_mod32(h_vals[1], b),
143
+ add_mod32(h_vals[2], c),
144
+ add_mod32(h_vals[3], d),
145
+ add_mod32(h_vals[4], e),
146
+ add_mod32(h_vals[5], f),
147
+ add_mod32(h_vals[6], g),
148
+ add_mod32(h_vals[7], h),
149
+ ]
150
+
151
+
152
+ def sha256(message):
153
+ # 统一转为字节
154
+ if isinstance(message, str):
155
+ msg_bytes = [ord(c) for c in message]
156
+ else:
157
+ msg_bytes = list(message)
158
+
159
+ # 填充
160
+ padded = pad_message(msg_bytes)
161
+
162
+ # 初始哈希值(拷贝一份,避免修改全局)
163
+ h_vals = [H0, H1, H2, H3, H4, H5, H6, H7]
164
+
165
+ # 逐块处理(每 64 字节一块)
166
+ for i in range(0, len(padded), 64):
167
+ block = padded[i:i+64]
168
+ h_vals = compress_block(block, h_vals)
169
+
170
+ # 拼接最终摘要
171
+ result = ''
172
+ for val in h_vals:
173
+ # 转 8 位十六进制(补零)
174
+ hex_str = hex(val)[2:] # 去掉 '0x'
175
+ if len(hex_str) < 8:
176
+ hex_str = '0' * (8 - len(hex_str)) + hex_str
177
+ result += hex_str
178
+
179
+ return result
180
+
181
+
182
+ def DJB2(s, capacity=0xffffffff):
183
+ h = 5381
184
+ for byte in s.encode('utf-8'):
185
+ h = ((h * 33) + byte) % capacity
186
+ return h % capacity