Skip to content

Commit 2ac236c

Browse files
committed
Add a hash method for strings
Hash constants are widely used in signatures, so I suggest adding a hash method for strings to obtain the hash constant of a string. For its usage example: ```meson hash_str = 'foobar'.hash('sha1') # return a sha1 constant # some process
1 parent 1e7f6f0 commit 2ac236c

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

docs/yaml/elementary/str.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ methods:
4141
description: The values to replace the @number@ placeholders in the format string.
4242
type: int | bool | str
4343

44+
# str.hash(algorithm)
45+
- name: hash
46+
description: Run the specified `algorithm` on the string and return the hash in hexadecimal
47+
returns: str
48+
example: |
49+
```meson
50+
message('foobar'.hash('md5')) # => '3858f62230ac3c915f300c664312c63f'
51+
message('foobar'.hash('sha1')) # => '8843d7f92416211de9ebb963ff4ce28125932878'
52+
message('foobar'.hash('sha256')) # => 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'
53+
...
54+
```
55+
56+
posargs:
57+
algorithm:
58+
description: |
59+
It supports the following algorithms:
60+
- md5
61+
- sha1
62+
- sha224
63+
- sha256
64+
- sha384
65+
- sha512
66+
- sha3_224
67+
- sha3_256
68+
- sha3_384
69+
- sha3_512
70+
type: str
71+
4472
# str.replace(old, new)
4573
- name: replace
4674
description: Search all occurrences of `old` and replace it with `new`

mesonbuild/interpreter/primitives/string.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
noPosargs,
2020
typed_pos_args,
2121
InvalidArguments,
22+
InterpreterException,
2223
FeatureBroken,
2324
stringifyUserArguments,
2425
)
@@ -83,6 +84,20 @@ def arg_replace(match: T.Match[str]) -> str:
8384

8485
return re.sub(r'@(\d+)@', arg_replace, self.held_object)
8586

87+
@noKwargs
88+
@typed_pos_args('str.hash', str)
89+
@InterpreterObject.method('hash')
90+
def hash_method(self, args: T.Tuple[T.List[TYPE_var]], kwargs: TYPE_kwargs) -> str:
91+
from hashlib import new
92+
try:
93+
# For supported algorithms
94+
# see https://docs.python.org/3/library/hashlib.html#hash-objects
95+
hash_obj = new(args[0]) # algorithm = args[0]
96+
hash_obj.update(self.held_object.encode())
97+
return hash_obj.hexdigest()
98+
except ValueError as e:
99+
raise InterpreterException(e)
100+
86101
@noKwargs
87102
@noPosargs
88103
@FeatureNew('str.splitlines', '1.2.0')

test cases/common/35 string operations/meson.build

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ long = 'abcde'
1919
prefix = 'abc'
2020
suffix = 'cde'
2121

22+
testcase expect_error('''unsupported hash type invalid-method''')
23+
long.hash('invalid-method')
24+
endtestcase
25+
26+
assert(long.hash('md5') == 'ab56b4d92b40713acc5af89985d4b786')
27+
assert(long.hash('sha1') == '03de6c570bfe24bfc328ccd7ca46b76eadaf4334')
28+
assert(long.hash('sha224') == 'bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6')
29+
assert(long.hash('sha256') == '36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c')
30+
assert(long.hash('sha3_224') == '6acfaab70afd8439cea3616b41088bd81c939b272548f6409cf30e57')
31+
assert(long.hash('sha3_256') == 'd716ec61e18904a8f58679b71cb065d4d5db72e0e0c3f155a4feff7add0e58eb')
32+
2233
assert(long[0] == 'a')
2334
assert(long[2] == 'c')
2435

0 commit comments

Comments
 (0)