Skip to main content

SIMD-accelerated string search, sort, hashes, fingerprints, & edit distances

Project description

StringZilla 🦖

StringZilla banner

The world wastes a minimum of $100M annually due to inefficient string operations. A typical codebase processes strings character by character, resulting in too many branches and data-dependencies, neglecting 90% of modern CPU's potential. LibC is different. It attempts to leverage SIMD instructions to boost some operations, and is often used by higher-level languages, runtimes, and databases. But it isn't perfect. 1️⃣ First, even on common hardware, including over a billion 64-bit ARM CPUs, common functions like strstr and memmem only achieve 1/3 of the CPU's thoughput. 2️⃣ Second, SIMD coverage is inconsistent: acceleration in forward scans does not guarantee speed in the reverse-order search. 3️⃣ At last, most high-level languages can't always use LibC, as the strings are often not NULL-terminated or may contain the Unicode "Zero" character in the middle of the string. That's why StringZilla was created. To provide predictably high performance, portable to any modern platform, operating system, and programming language.

StringZilla Python installs StringZilla Rust installs GitHub Actions Workflow Status GitHub Actions Workflow Status GitHub Actions Workflow Status GitHub Actions Workflow Status StringZilla code size

StringZilla is the GodZilla of string libraries, using SIMD and SWAR to accelerate string operations on modern CPUs. It is up to 10x faster than the default and even other SIMD-accelerated string libraries in C, C++, Python, and other languages, while covering broad functionality. It accelerates exact and fuzzy string matching, edit distance computations, sorting, lazily-evaluated ranges to avoid memory allocations, and even random-string generators.

  • 🐂 C : Upgrade LibC's <string.h> to <stringzilla.h> in C 99
  • 🐉 C++: Upgrade STL's <string> to <stringzilla.hpp> in C++ 11
  • 🐍 Python: Upgrade your str to faster Str
  • 🍎 Swift: Use the String+StringZilla extension
  • 🦀 Rust: Use the StringZilla traits crate
  • 🐚 Shell: Accelerate common CLI tools with sz_ prefix
  • 📚 Researcher? Jump to Algorithms & Design Decisions
  • 💡 Thinking to contribute? Look for "good first issues"
  • 🤝 And check the guide to setup the environment
  • Want more bindings or features? Let me know!

Who is this for?

  • For data-engineers parsing large datasets, like the CommonCrawl, RedPajama, or LAION.
  • For software engineers optimizing strings in their apps and services.
  • For bioinformaticians and search engineers looking for edit-distances for USearch.
  • For DBMS devs, optimizing LIKE, ORDER BY, and GROUP BY operations.
  • For hardware designers, needing a SWAR baseline for strings-processing functionality.
  • For students studying SIMD/SWAR applications to non-data-parallel operations.

Performance

C C++ Python StringZilla
find the first occurrence of a random word from text, ≅ 5 bytes long
strstr 1
x86: 7.4 · arm: 2.0 GB/s
.find
x86: 2.9 · arm: 1.6 GB/s
.find
x86: 1.1 · arm: 0.6 GB/s
sz_find
x86: 10.6 · arm: 7.1 GB/s
find the last occurrence of a random word from text, ≅ 5 bytes long
.rfind
x86: 0.5 · arm: 0.4 GB/s
.rfind
x86: 0.9 · arm: 0.5 GB/s
sz_rfind
x86: 10.8 · arm: 6.7 GB/s
split lines separated by \n or \r 2
strcspn 1
x86: 5.42 · arm: 2.19 GB/s
.find_first_of
x86: 0.59 · arm: 0.46 GB/s
re.finditer
x86: 0.06 · arm: 0.02 GB/s
sz_find_charset
x86: 4.08 · arm: 3.22 GB/s
find the last occurrence of any of 6 whitespaces 2
.find_last_of
x86: 0.25 · arm: 0.25 GB/s
sz_rfind_charset
x86: 0.43 · arm: 0.23 GB/s
Random string from a given alphabet, 20 bytes long 5
rand() % n
x86: 18.0 · arm: 9.4 MB/s
uniform_int_distribution
x86: 47.2 · arm: 20.4 MB/s
join(random.choices(...))
x86: 13.3 · arm: 5.9 MB/s
sz_generate
x86: 56.2 · arm: 25.8 MB/s
Get sorted order, ≅ 8 million English words 6
qsort_r
x86: 3.55 · arm: 5.77 s
std::sort
x86: 2.79 · arm: 4.02 s
numpy.argsort
x86: 7.58 · arm: 13.00 s
sz_sort
x86: 1.91 · arm: 2.37 s
Levenshtein edit distance, ≅ 5 bytes long
via jellyfish 3
x86: 1,550 · arm: 2,220 ns
sz_edit_distance
x86: 99 · arm: 180 ns
Needleman-Wunsch alignment scores, ≅ 10 K aminoacids long
via biopython 4
x86: 257 · arm: 367 ms
sz_alignment_score
x86: 73 · arm: 177 ms

StringZilla has a lot of functionality, most of which is covered by benchmarks across C, C++, Python and other languages. You can find those in the ./scripts directory, with usage notes listed in the CONTRIBUTING.md file. Notably, if the CPU supports misaligned loads, even the 64-bit SWAR backends are faster than either standard library.

Most benchmarks were conducted on a 1 GB English text corpus, with an average word length of 5 characters. The code was compiled with GCC 12, using glibc v2.35. The benchmarks performed on Arm-based Graviton3 AWS c7g instances and r7iz Intel Sapphire Rapids. Most modern Arm-based 64-bit CPUs will have similar relative speedups. Variance withing x86 CPUs will be larger. 1 Unlike other libraries, LibC requires strings to be NULL-terminated. 2 Six whitespaces in the ASCII set are: \t\n\v\f\r. Python's and other standard libraries have specialized functions for those. 3 Most Python libraries for strings are also implemented in C. 4 Unlike the rest of BioPython, the alignment score computation is implemented in C. 5 All modulo operations were conducted with uint8_t to allow compilers more optimization opportunities. The C++ STL and StringZilla benchmarks used a 64-bit Mersenne Twister as the generator. For C, C++, and StringZilla, an in-place update of the string was used. In Python every string had to be allocated as a new object, which makes it less fair. 6 Contrary to the popular opinion, Python's default sorted function works faster than the C and C++ standard libraries. That holds for large lists or tuples of strings, but fails as soon as you need more complex logic, like sorting dictionaries by a string key, or producing the "sorted order" permutation. The latter is very common in database engines and is most similar to numpy.argsort. Current StringZilla solution can be at least 4x faster without loss of generality.

Functionality

StringZilla is compatible with most modern CPUs, and provides a broad range of functionality.

  • works on both Little-Endian and Big-Endian architectures.
  • works on 32-bit and 64-bit hardware architectures.
  • compatible with ASCII and UTF-8 encoding.

Not all features are available across all bindings. Consider contributing, if you need a feature that's not yet implemented.

Maturity C 99 C++ 11 Python Swift Rust
Substring Search 🌳
Character Set Search 🌳
Edit Distances 🧐
Small String Class 🧐
Sorting & Sequence Operations 🚧
Lazy Ranges, Compressed Arrays 🧐
Hashes & Fingerprints 🚧

🌳 parts are used in production. 🧐 parts are in beta. 🚧 parts are under active development, and are likely to break in subsequent releases. ✅ are implemented. ⚪ are considered. ❌ are not intended.

Quick Start: Python 🐍

  1. Install via pip: pip install stringzilla
  2. Import the classes you need: from stringzilla import Str, Strs, File

Basic Usage

If you've ever used the Python str, bytes, bytearray, memoryview class, you'll know what to expect. StringZilla's Str class is a hybrid of those two, providing str-like interface to byte-arrays.

from stringzilla import Str, File

text_from_str = Str('some-string') # no copies, just a view
text_from_file = Str(File('some-file.txt')) # memory-mapped file

The File class memory-maps a file from persistent memory without loading its copy into RAM. The contents of that file would remain immutable, and the mapping can be shared by multiple Python processes simultaneously. A standard dataset pre-processing use case would be to map a sizeable textual dataset like Common Crawl into memory, spawn child processes, and split the job between them.

Basic Operations

  • Length: len(text) -> int
  • Indexing: text[42] -> str
  • Slicing: text[42:46] -> Str
  • Substring check: 'substring' in text -> bool
  • Hashing: hash(text) -> int
  • String conversion: str(text) -> str

Advanced Operations

import sys

x: bool = text.contains('substring', start=0, end=sys.maxsize)
x: int = text.find('substring', start=0, end=sys.maxsize)
x: int = text.count('substring', start=0, end=sys.maxsize, allowoverlap=False)
x: str = text.decode(encoding='utf-8', errors='strict')
x: Strs = text.split(separator=' ', maxsplit=sys.maxsize, keepseparator=False)
x: Strs = text.rsplit(separator=' ', maxsplit=sys.maxsize, keepseparator=False)
x: Strs = text.splitlines(keeplinebreaks=False, maxsplit=sys.maxsize)

It's important to note, that the last function behavior is slightly different from Python's str.splitlines. The native version matches \n, \r, \v or \x0b, \f or \x0c, \x1c, \x1d, \x1e, \x85, \r\n, \u2028, \u2029, including 3x two-bytes-long runes. The StringZilla version matches only \n, \v, \f, \r, \x1c, \x1d, \x1e, \x85, avoiding two-byte-long runes.

Character Set Operations

Python strings don't natively support character set operations. This forces people to use regular expressions, which are slow and hard to read. To avoid the need for re.finditer, StringZilla provides the following interfaces:

x: int = text.find_first_of('chars', start=0, end=sys.maxsize)
x: int = text.find_last_of('chars', start=0, end=sys.maxsize)
x: int = text.find_first_not_of('chars', start=0, end=sys.maxsize)
x: int = text.find_last_not_of('chars', start=0, end=sys.maxsize)
x: Strs = text.split_charset(separator='chars', maxsplit=sys.maxsize, keepseparator=False)
x: Strs = text.rsplit_charset(separator='chars', maxsplit=sys.maxsize, keepseparator=False)

Collection-Level Operations

Once split into a Strs object, you can sort, shuffle, and reorganize the slices, with minimum memory footprint. If all the chunks are located in consecutive memory regions, the memory overhead can be as low as 4 bytes per chunk.

lines: Strs = text.split(separator='\n') # 4 bytes per line overhead for under 4 GB of text
batch: Strs = lines.sample(seed=42) # 10x faster than `random.choices`
lines.shuffle(seed=42) # or shuffle all lines in place and shard with slices
# WIP: lines.sort() # explodes to 16 bytes per line overhead for any length text
# WIP: sorted_order: tuple = lines.argsort() # similar to `numpy.argsort`

Working on RedPajama, addressing 20 Billion annotated english documents, one will need only 160 GB of RAM instead of Terabytes. Once loaded, the data will be memory-mapped, and can be reused between multiple Python processes without copies. And of course, you can use slices to navigate the dataset and shard it between multiple workers.

lines[::3] # every third line
lines[1::1] # every odd line
lines[:-100:-1] # last 100 lines in reverse order

Iterators and Memory Efficiency

Python's operations like split() and readlines() immediately materialize a list of copied parts. This can be very memory-inefficient for large datasets. StringZilla saves a lot of memory by viewing existing memory regions as substrings, but even more memory can be saved by using lazily evaluated iterators.

x: SplitIterator[Str] = text.split_iter(separator=' ', keepseparator=False)
x: SplitIterator[Str] = text.rsplit_iter(separator=' ', keepseparator=False)
x: SplitIterator[Str] = text.split_charset_iter(separator='chars', keepseparator=False)
x: SplitIterator[Str] = text.rsplit_charset_iter(separator='chars', keepseparator=False)

StringZilla can easily be 10x more memory efficient than native Python classes for tokenization. With lazy operations, it practically becomes free.

import stringzilla as sz
%load_ext memory_profiler

text = open("enwik9.txt", "r").read() # 1 GB, mean word length 7.73 bytes
%memit text.split() # increment: 8670.12 MiB (152 ms)
%memit sz.split(text) # increment: 530.75 MiB (25 ms)
%memit sum(1 for _ in sz.split_iter(text)) # increment: 0.00 MiB

Low-Level Python API

Aside from calling the methods on the Str and Strs classes, you can also call the global functions directly on str and bytes instances. Assuming StringZilla CPython bindings are implemented without any intermediate tools like SWIG or PyBind, the call latency should be similar to native classes.

import stringzilla as sz

contains: bool = sz.contains("haystack", "needle", start=0, end=sys.maxsize)
offset: int = sz.find("haystack", "needle", start=0, end=sys.maxsize)
count: int = sz.count("haystack", "needle", start=0, end=sys.maxsize, allowoverlap=False)

Edit Distances

assert sz.edit_distance("apple", "aple") == 1 # skip one ASCII character
assert sz.edit_distance("αβγδ", "αγδ") == 2 # skip two bytes forming one rune
assert sz.edit_distance_unicode("αβγδ", "αγδ") == 1 # one unicode rune

Several Python libraries provide edit distance computation. Most of them are implemented in C, but are not always as fast as StringZilla. Taking a 1'000 long proteins around 10'000 characters long, computing just a 100 distances:

Moreover, you can pass custom substitution matrices to compute the Needleman-Wunsch alignment scores. That task is very common in bioinformatics and computational biology. It's natively supported in BioPython, and its BLOSUM matrices can be converted to StringZilla's format. Alternatively, you can construct an arbitrary 256 by 256 cost matrix using NumPy. Depending on arguments, the result may be equal to the negative Levenshtein distance.

import numpy as np
import stringzilla as sz

costs = np.zeros((256, 256), dtype=np.int8)
costs.fill(-1)
np.fill_diagonal(costs, 0)

assert sz.alignment_score("first", "second", substitution_matrix=costs, gap_score=-1) == -sz.edit_distance(a, b)

Using the same proteins as for Levenshtein distance benchmarks:

§ Example converting from BioPython to StringZilla.
import numpy as np
from Bio import Align
from Bio.Align import substitution_matrices

aligner = Align.PairwiseAligner()
aligner.substitution_matrix = substitution_matrices.load("BLOSUM62")
aligner.open_gap_score = 1
aligner.extend_gap_score = 1

# Convert the matrix to NumPy
subs_packed = np.array(aligner.substitution_matrix).astype(np.int8)
subs_reconstructed = np.zeros((256, 256), dtype=np.int8)

# Initialize all banned characters to a the largest possible penalty
subs_reconstructed.fill(127)
for packed_row, packed_row_aminoacid in enumerate(aligner.substitution_matrix.alphabet):
    for packed_column, packed_column_aminoacid in enumerate(aligner.substitution_matrix.alphabet):
        reconstructed_row = ord(packed_row_aminoacid)
        reconstructed_column = ord(packed_column_aminoacid)
        subs_reconstructed[reconstructed_row, reconstructed_column] = subs_packed[packed_row, packed_column]

# Let's pick two examples for of tri-peptides (made of 3 aminoacids)
glutathione = "ECG" # Need to rebuild human tissue?
thyrotropin_releasing_hormone = "QHP" # Or to regulate your metabolism?

assert sz.alignment_score(
    glutathione,
    thyrotropin_releasing_hormone, 
    substitution_matrix=subs_reconstructed, 
    gap_score=1) == aligner.score(glutathione, thyrotropin_releasing_hormone) # Equal to 6

Serialization

Filesystem

Similar to how File can be used to read a large file, other interfaces can be used to dump strings to disk faster. The Str class has write_to to write the string to a file, and offset_within to obtain integer offsets of substring view in larger string for navigation.

web_archieve = Str("<html>...</html><html>...</html>")
_, end_tag, next_doc = web_archieve.partition("</html>") # or use `find`
next_doc_offset = next_doc.offset_within(web_archieve)
web_archieve.write_to("next_doc.html") # no GIL, no copies, just a view

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow import foreign_buffer
from stringzilla import Str

original = "hello"
view = Str(native)
arrow = foreign_buffer(view.address, view.nbytes, view)

That means you can convert Str to pyarrow.Buffer and Strs to pyarrow.Array without extra copies.

Quick Start: C/C++ 🛠️

The C library is header-only, so you can just copy the stringzilla.h header into your project. Same applies to C++, where you would copy the stringzilla.hpp header. Alternatively, add it as a submodule, and include it in your build system.

git submodule add https://github.com/ashvardanian/stringzilla.git

Or using a pure CMake approach:

FetchContent_Declare(stringzilla GIT_REPOSITORY https://github.com/ashvardanian/stringzilla.git)
FetchContent_MakeAvailable(stringzilla)

Last, but not the least, you can also install it as a library, and link against it. This approach is worse for inlining, but brings dynamic runtime dispatch for the most advanced CPU features.

Basic Usage with C 99 and Newer

There is a stable C 99 interface, where all function names are prefixed with sz_. Most interfaces are well documented, and come with self-explanatory names and examples. In some cases, hardware specific overloads are available, like sz_find_avx512 or sz_find_neon. Both are companions of the sz_find, first for x86 CPUs with AVX-512 support, and second for Arm NEON-capable CPUs.

#include <stringzilla/stringzilla.h>

// Initialize your haystack and needle
sz_string_view_t haystack = {your_text, your_text_length};
sz_string_view_t needle = {your_subtext, your_subtext_length};

// Perform string-level operations
sz_size_t substring_position = sz_find(haystack.start, haystack.length, needle.start, needle.length);
sz_size_t substring_position = sz_find_avx512(haystack.start, haystack.length, needle.start, needle.length);
sz_size_t substring_position = sz_find_neon(haystack.start, haystack.length, needle.start, needle.length);

// Hash strings
sz_u64_t hash = sz_hash(haystack.start, haystack.length);

// Perform collection level operations
sz_sequence_t array = {your_order, your_count, your_get_start, your_get_length, your_handle};
sz_sort(&array, &your_config);
§ Mapping from LibC to StringZilla.

By design, StringZilla has a couple of notable differences from LibC:

  1. all strings are expected to have a length, and are not necessarily null-terminated.
  2. every operations has a reverse order counterpart.

That way sz_find and sz_rfind are similar to strstr and strrstr in LibC. Similarly, sz_find_byte and sz_rfind_byte replace memchr and memrchr. The sz_find_charset maps to strspn and strcspn, while sz_rfind_charset has no sibling in LibC.

LibC Functionality StringZilla Equivalents
memchr(haystack, needle, haystack_length), strchr sz_find_byte(haystack, haystack_length, needle)
memrchr(haystack, needle, haystack_length) sz_rfind_byte(haystack, haystack_length, needle)
memcmp, strcmp sz_order, sz_equal
strlen(haystack) sz_find_byte(haystack, haystack_length, needle)
strcspn(haystack, needles) sz_rfind_charset(haystack, haystack_length, needles_bitset)
strspn(haystack, needles) sz_find_charset(haystack, haystack_length, needles_bitset)
memmem(haystack, haystack_length, needle, needle_length), strstr sz_find(haystack, haystack_length, needle, needle_length)
memcpy(destination, source, destination_length) sz_copy(destination, source, destination_length)
memmove(destination, source, destination_length) sz_move(destination, source, destination_length)
memset(destination, value, destination_length) sz_fill(destination, destination_length, value)

Basic Usage with C++ 11 and Newer

There is a stable C++ 11 interface available in the ashvardanian::stringzilla namespace. It comes with two STL-like classes: string_view and string. The first is a non-owning view of a string, and the second is a mutable string with a Small String Optimization.

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

sz::string haystack = "some string";
sz::string_view needle = sz::string_view(haystack).substr(0, 4);

auto substring_position = haystack.find(needle); // Or `rfind`
auto hash = std::hash<sz::string_view>(haystack); // Compatible with STL's `std::hash`

haystack.end() - haystack.begin() == haystack.size(); // Or `rbegin`, `rend`
haystack.find_first_of(" \w\t") == 4; // Or `find_last_of`, `find_first_not_of`, `find_last_not_of`
haystack.starts_with(needle) == true; // Or `ends_with`
haystack.remove_prefix(needle.size()); // Why is this operation in-place?!
haystack.contains(needle) == true; // STL has this only from C++ 23 onwards
haystack.compare(needle) == 1; // Or `haystack <=> needle` in C++ 20 and beyond

StringZilla also provides string literals for automatic type resolution, similar to STL:

using sz::literals::operator""_sz;
using std::literals::operator""sv;

auto a = "some string"; // char const *
auto b = "some string"sv; // std::string_view
auto b = "some string"_sz; // sz::string_view

Memory Ownership and Small String Optimization

Most operations in StringZilla don't assume any memory ownership. But in addition to the read-only search-like operations StringZilla provides a minimalistic C and C++ implementations for a memory owning string "class". Like other efficient string implementations, it uses the Small String Optimization (SSO) to avoid heap allocations for short strings.

typedef union sz_string_t {
    struct internal {
        sz_ptr_t start;
        sz_u8_t length;
        char chars[SZ_STRING_INTERNAL_SPACE]; /// Ends with a null-terminator.
    } internal;

    struct external {
        sz_ptr_t start;
        sz_size_t length;        
        sz_size_t space; /// The length of the heap-allocated buffer.
        sz_size_t padding;
    } external;

} sz_string_t;

As one can see, a short string can be kept on the stack, if it fits within internal.chars array. Before 2015 GCC string implementation was just 8 bytes, and could only fit 7 characters. Different STL implementations today have different thresholds for the Small String Optimization. Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit 22 characters on stack. Our layout might be preferential, if you want to avoid branches. If you use a different compiler, you may want to check it's SSO buffer size with a simple Gist.

libstdc++ in GCC 13 libc++ in Clang 17 StringZilla
sizeof(std::string) 32 24 32
Small String Capacity 15 22 22

This design has been since ported to many high-level programming languages. Swift, for example, can store 15 bytes in the String instance itself. StringZilla implements SSO at the C level, providing the sz_string_t union and a simple API for primary operations.

sz_memory_allocator_t allocator;
sz_string_t string;

// Init and make sure we are on stack
sz_string_init(&string);
sz_string_is_on_stack(&string); // == sz_true_k

// Optionally pre-allocate space on the heap for future insertions.
sz_string_grow(&string, 100, &allocator); // == sz_true_k

// Append, erase, insert into the string.
sz_string_expand(&string, 0, "_Hello_", 7, &allocator); // == sz_true_k
sz_string_expand(&string, SZ_SIZE_MAX, "world", 5, &allocator); // == sz_true_k
sz_string_erase(&string, 0, 1);

// Unpacking & introspection.
sz_ptr_t string_start;
sz_size_t string_length;
sz_size_t string_space;
sz_bool_t string_is_external;
sz_string_unpack(string, &string_start, &string_length, &string_space, &string_is_external);
sz_equal(string_start, "Hello_world", 11); // == sz_true_k

// Reclaim some memory.
sz_string_shrink_to_fit(&string, &allocator); // == sz_true_k
sz_string_free(&string, &allocator);

Unlike the conventional C strings, the sz_string_t is allowed to contain null characters. To safely print those, pass the string_length to printf as well.

printf("%.*s\n", (int)string_length, string_start);

What's Wrong with the C++ Standard Library?

C++ Code Evaluation Result Invoked Signature
"Loose"s.replace(2, 2, "vath"s, 1) "Loathe" 🤢 (pos1, count1, str2, pos2)
"Loose"s.replace(2, 2, "vath", 1) "Love" 🥰 (pos1, count1, str2, count2)

StringZilla is designed to be a drop-in replacement for the C++ Standard Templates Library. That said, some of the design decisions of STL strings are highly controversial, error-prone, and expensive. Most notably:

  1. Argument order for replace, insert, erase and similar functions is impossible to guess.
  2. Bounds-checking exceptions for substr-like functions are only thrown for one side of the range.
  3. Returning string copies in substr-like functions results in absurd volume of allocations.
  4. Incremental construction via push_back-like functions goes through too many branches.
  5. Inconsistency between string and string_view methods, like the lack of remove_prefix and remove_suffix.

Check the following set of asserts validating the std::string specification. It's not realistic to expect the average developer to remember the 14 overloads of std::string::replace.

using str = std::string;

assert(str("hello world").substr(6) == "world");
assert(str("hello world").substr(6, 100) == "world"); // 106 is beyond the length of the string, but its OK
assert_throws(str("hello world").substr(100), std::out_of_range);   // 100 is beyond the length of the string
assert_throws(str("hello world").substr(20, 5), std::out_of_range); // 20 is beyond the length of the string
assert_throws(str("hello world").substr(-1, 5), std::out_of_range); // -1 casts to unsigned without any warnings...
assert(str("hello world").substr(0, -1) == "hello world");          // -1 casts to unsigned without any warnings...

assert(str("hello").replace(1, 2, "123") == "h123lo");
assert(str("hello").replace(1, 2, str("123"), 1) == "h23lo");
assert(str("hello").replace(1, 2, "123", 1) == "h1lo");
assert(str("hello").replace(1, 2, "123", 1, 1) == "h2lo");
assert(str("hello").replace(1, 2, str("123"), 1, 1) == "h2lo");
assert(str("hello").replace(1, 2, 3, 'a') == "haaalo");
assert(str("hello").replace(1, 2, {'a', 'b'}) == "hablo");

To avoid those issues, StringZilla provides an alternative consistent interface. It supports signed arguments, and doesn't have more than 3 arguments per function or The standard API and our alternative can be conditionally disabled with SZ_SAFETY_OVER_COMPATIBILITY=1. When it's enabled, the subjectively risky overloads from the Standard will be disabled.

using str = sz::string;

str("a:b").front(1) == "a"; // no checks, unlike `substr`
str("a:b").back(-1) == "b"; // accepting negative indices
str("a:b").sub(1, -1) == ":"; // similar to Python's `"a:b"[1:-1]`
str("a:b").sub(-2, -1) == ":"; // similar to Python's `"a:b"[-2:-1]`
str("a:b").sub(-2, 1) == ""; // similar to Python's `"a:b"[-2:1]`
"a:b"_sz[{-2, -1}] == ":"; // works on views and overloads `operator[]`

Assuming StringZilla is a header-only library you can use the full API in some translation units and gradually transition to safer restricted API in others. Bonus - all the bound checking is branchless, so it has a constant cost and won't hurt your branch predictor.

Beyond the C++ Standard Library - Learning from Python

Python is arguably the most popular programming language for data science. In part, that's due to the simplicity of its standard interfaces. StringZilla brings some of that functionality to C++.

  • Content checks: isalnum, isalpha, isascii, isdigit, islower, isspace, isupper.
  • Trimming character sets: lstrip, rstrip, strip.
  • Trimming string matches: remove_prefix, remove_suffix.
  • Ranges of search results: splitlines, split, rsplit.
  • Number of non-overlapping substring matches: count.
  • Partitioning: partition, rpartition.

For example, when parsing documents, it is often useful to split it into substrings. Most often, after that, you would compute the length of the skipped part, the offset and the length of the remaining part. This results in a lot of pointer arithmetic and is error-prone. StringZilla provides a convenient partition function, which returns a tuple of three string views, making the code cleaner.

auto parts = haystack.partition(':'); // Matching a character
auto [before, match, after] = haystack.partition(':'); // Structure unpacking
auto [before, match, after] = haystack.partition(char_set(":;")); // Character-set argument
auto [before, match, after] = haystack.partition(" : "); // String argument
auto [before, match, after] = haystack.rpartition(sz::whitespaces); // Split around the last whitespace

Combining those with the split function, one can easily parse a CSV file or HTTP headers.

for (auto line : haystack.split("\r\n")) {
    auto [key, _, value] = line.partition(':');
    headers[key.strip()] = value.strip();
}

Some other extensions are not present in the Python standard library either. Let's go through the C++ functionality category by category.

Some of the StringZilla interfaces are not available even Python's native str class. Here is a sneak peek of the most useful ones.

text.hash(); // -> 64 bit unsigned integer 
text.ssize(); // -> 64 bit signed length to avoid `static_cast<std::ssize_t>(text.size())`
text.contains_only(" \w\t"); // == text.find_first_not_of(char_set(" \w\t")) == npos;
text.contains(sz::whitespaces); // == text.find(char_set(sz::whitespaces)) != npos;

// Simpler slicing than `substr`
text.front(10); // -> sz::string_view
text.back(10); // -> sz::string_view

// Safe variants, which clamp the range into the string bounds
using sz::string::cap;
text.front(10, cap) == text.front(std::min(10, text.size()));
text.back(10, cap) == text.back(std::min(10, text.size()));

// Character set filtering
text.lstrip(sz::whitespaces).rstrip(sz::newlines); // like Python
text.front(sz::whitespaces); // all leading whitespaces
text.back(sz::digits); // all numerical symbols forming the suffix

// Incremental construction
using sz::string::unchecked;
text.push_back('x'); // no surprises here
text.push_back('x', unchecked); // no bounds checking, Rust style
text.try_push_back('x'); // returns `false` if the string is full and the allocation failed

sz::concatenate(text, "@", domain, ".", tld); // No allocations

Splits and Ranges

One of the most common use cases is to split a string into a collection of substrings. Which would often result in StackOverflow lookups and snippets like the one below.

std::vector<std::string> lines = split(haystack, "\r\n"); // string delimiter
std::vector<std::string> words = split(lines, ' '); // character delimiter

Those allocate memory for each string and the temporary vectors. Each allocation can be orders of magnitude more expensive, than even serial for-loop over characters. To avoid those, StringZilla provides lazily-evaluated ranges, compatible with the Range-v3 library.

for (auto line : haystack.split("\r\n"))
    for (auto word : line.split(char_set(" \w\t.,;:!?")))
        std::cout << word << std::endl;

Each of those is available in reverse order as well. It also allows interleaving matches, if you want both inclusions of xx in xxx. Debugging pointer offsets is not a pleasant exercise, so keep the following functions in mind.

  • haystack.[r]find_all(needle, interleaving)
  • haystack.[r]find_all(char_set(""))
  • haystack.[r]split(needle)
  • haystack.[r]split(char_set(""))

For $N$ matches the split functions will report $N+1$ matches, potentially including empty strings. Ranges have a few convenience methods as well:

range.size(); // -> std::size_t
range.empty(); // -> bool
range.template to<std::set<std::sting>>(); 
range.template to<std::vector<std::sting_view>>(); 

Concatenating Strings without Allocations

Another common string operation is concatenation. The STL provides std::string::operator+ and std::string::append, but those are not very efficient, if multiple invocations are performed.

std::string name, domain, tld;
auto email = name + "@" + domain + "." + tld; // 4 allocations

The efficient approach would be to pre-allocate the memory and copy the strings into it.

std::string email;
email.reserve(name.size() + domain.size() + tld.size() + 2);
email.append(name), email.append("@"), email.append(domain), email.append("."), email.append(tld);

That's mouthful and error-prone. StringZilla provides a more convenient concatenate function, which takes a variadic number of arguments. It also overrides the operator| to concatenate strings lazily, without any allocations.

auto email = sz::concatenate(name, "@", domain, ".", tld);   // 0 allocations
auto email = name | "@" | domain | "." | tld;                // 0 allocations
sz::string email = name | "@" | domain | "." | tld;          // 1 allocations

Random Generation

Software developers often need to generate random strings for testing purposes. The STL provides std::generate and std::random_device, that can be used with StringZilla.

sz::string random_string(std::size_t length, char const *alphabet, std::size_t cardinality) {
    sz::string result(length, '\0');
    static std::random_device seed_source; // Too expensive to construct every time
    std::mt19937 generator(seed_source());
    std::uniform_int_distribution<std::size_t> distribution(0, cardinality);
    std::generate(result.begin(), result.end(), [&]() { return alphabet[distribution(generator)]; });
    return result;
}

Mouthful and slow. StringZilla provides a C native method - sz_generate and a convenient C++ wrapper - sz::generate. Similar to Python it also defines the commonly used character sets.

auto protein = sz::string::random(300, "ARNDCQEGHILKMFPSTWYV"); // static method
auto dna = sz::basic_string<custom_allocator>::random(3_000_000_000, "ACGT");

dna.randomize("ACGT"); // `noexcept` pre-allocated version
dna.randomize(&std::rand, "ACGT"); // pass any generator, like `std::mt19937`

char uuid[36];
sz::randomize(sz::string_span(uuid, 36), "0123456789abcdef-"); // Overwrite any buffer

Levenshtein Edit Distance and Alignment Scores

Levenshtein and Hamming edit distance are provided for both byte-strings and UTF-8 strings. The latter will output the distance in Unicode code points, not bytes. Needleman-Wunsch alignment scores are only defined for byte-strings.

// Count number of substitutions in same length strings
sz::hamming_distance(first, second[, upper_bound]) -> std::size_t;
sz::hamming_distance_utf8(first, second[, upper_bound]) -> std::size_t;

// Count number of insertions, deletions and substitutions
sz::edit_distance(first, second[, upper_bound[, allocator]]) -> std::size_t;
sz::edit_distance_utf8(first, second[, upper_bound[, allocator]]) -> std::size_t;

// Substitution-parametrized Needleman-Wunsch global alignment score
std::int8_t costs[256][256]; // Substitution costs matrix
sz::alignment_score(first, second, costs[, gap_score[, allocator]) -> std::ptrdiff_t;

Sorting in C and C++

LibC provides qsort and STL provides std::sort. Both have their quarks. The LibC standard has no way to pass a context to the comparison function, that's only possible with platform-specific extensions. Those have different arguments order on every OS.

// Linux: https://linux.die.net/man/3/qsort_r
void qsort_r(void *elements, size_t count, size_t element_width, 
    int (*compare)(void const *left, void const *right, void *context),
    void *context);
// MacOS and FreeBSD: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/qsort_r.3.html
void qsort_r(void *elements, size_t count, size_t element_width, 
    void *context,
    int (*compare)(void *context, void const *left, void const *right));
// Windows conflicts with ISO `qsort_s`: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/qsort-s?view=msvc-170
void qsort_s(id *elements, size_t count, size_t element_width, 
    int (*compare)(void *context, void const *left, void const *right),
    void *context);

C++ generic algorithm is not perfect either. There is no guarantee in the standard that std::sort won't allocate any memory. If you are running on embedded, in real-time or on 100+ CPU cores per node, you may want to avoid that. StringZilla doesn't solve the general case, but hopes to improve the performance for strings. Use sz_sort, or the high-level sz::sorted_order, which can be used sort any collection of elements convertible to sz::string_view.

std::vector<std::string> data({"c", "b", "a"});
std::vector<std::size_t> order = sz::sorted_order(data); //< Simple shortcut

// Or, taking care of memory allocation:
sz::sorted_order(data.begin(), data.end(), order.data(), [](auto const &x) -> sz::string_view { return x; });

Standard C++ Containers with String Keys

The C++ Standard Templates Library provides several associative containers, often used with string keys.

std::map<std::string, int, std::less<std::string>> sorted_words;
std::unordered_map<std::string, int, std::hash<std::string>, std::equal_to<std::string>> words;

The performance of those containers is often limited by the performance of the string keys, especially on reads. StringZilla can be used to accelerate containers with std::string keys, by overriding the default comparator and hash functions.

std::map<std::string, int, sz::string_view_less> sorted_words;
std::unordered_map<std::string, int, sz::string_view_hash, sz::string_view_equal_to> words;

Alternatively, a better approach would be to use the sz::string class as a key. The right hash function and comparator would be automatically selected and the performance gains would be more noticeable if the keys are short.

std::map<sz::string, int> sorted_words;
std::unordered_map<sz::string, int> words;

Compilation Settings and Debugging

SZ_DEBUG:

For maximal performance, the C library does not perform any bounds checking in Release builds. In C++, bounds checking happens only in places where the STL std::string would do it. If you want to enable more aggressive bounds-checking, define SZ_DEBUG before including the header. If not explicitly set, it will be inferred from the build type.

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

One can explicitly disable certain families of SIMD instructions for compatibility purposes. Default values are inferred at compile time.

SZ_DYNAMIC_DISPATCH:

By default, StringZilla is a header-only library. But if you are running on different generations of devices, it makes sense to pre-compile the library for all supported generations at once, and dispatch at runtime. This flag does just that and is used to produce the stringzilla.so shared library, as well as the Python bindings.

SZ_USE_MISALIGNED_LOADS:

By default, StringZilla avoids misaligned loads. If supported, it replaces many byte-level operations with word-level ones. Going from char-like types to uint64_t-like ones can significantly accelerate the serial (SWAR) backend. So consider enabling it if you are building for some embedded device.

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

When using the C header-only library one can disable the use of LibC. This may affect the type resolution system on obscure hardware platforms. Moreover, one may let stringzilla override the common symbols like the memcpy and memset with its own implementations. In that case you can use the LD_PRELOAD trick to prioritize it's symbols over the ones from the LibC and accelerate existing string-heavy applications without recompiling them.

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

When using the C++ interface one can disable implicit conversions from std::string to sz::string and back. If not needed, the <string> and <string_view> headers will be excluded, reducing compilation time. Moreover, if STL compatibility is a low priority, one can make the API safer by disabling the overloads, which are subjectively error prone.

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

When compiling the tests and benchmarks, you can explicitly set the target hardware architecture. It's synonymous to GCC's -march flag and is used to enable/disable the appropriate instruction sets. You can also disable the shared library build, if you don't need it.

Quick Start: Rust 🦀

StringZilla is available as a Rust crate. Some of the interfaces will look familiar to the users of the memchr crate.

use stringzilla::sz;

// Identical to `memchr::memmem::find` and `memchr::memmem::rfind` functions
sz::find("Hello, world!", "world") // 7
sz::rfind("Hello, world!", "world") // 7

// Generalizations of `memchr::memrchr[123]`
sz::find_char_from("Hello, world!", "world") // 2
sz::rfind_char_from("Hello, world!", "world") // 11

Unlike memchr, the throughput of stringzilla is high in both normal and reverse-order searches. It also provides no constraints on the size of the character set, while memchr allows only 1, 2, or 3 characters. In addition to global functions, stringzilla provides a StringZilla extension trait:

use stringzilla::StringZilla;

let my_string: String = String::from("Hello, world!");
let my_str = my_string.as_str();
let my_cow_str = Cow::from(&my_string);

// Use the generic function with a String
assert_eq!(my_string.sz_find("world"), Some(7));
assert_eq!(my_string.sz_rfind("world"), Some(7));
assert_eq!(my_string.sz_find_char_from("world"), Some(2));
assert_eq!(my_string.sz_rfind_char_from("world"), Some(11));
assert_eq!(my_string.sz_find_char_not_from("world"), Some(0));
assert_eq!(my_string.sz_rfind_char_not_from("world"), Some(12));

// Same works for &str and Cow<'_, str>
assert_eq!(my_str.sz_find("world"), Some(7));
assert_eq!(my_cow_str.as_ref().sz_find("world"), Some(7));

The library also exposes Levenshtein and Hamming edit-distances for byte-arrays and UTF-8 strings, as well as Needleman-Wunch alignment scores.

use stringzilla::sz;

// Handling arbitrary byte arrays:
sz::edit_distance("Hello, world!", "Hello, world?"); // 1
sz::hamming_distance("Hello, world!", "Hello, world?"); // 1
sz::alignment_score("Hello, world!", "Hello, world?", sz::unary_substitution_costs(), -1); // -1

// Handling UTF-8 strings:
sz::hamming_distance_utf8("αβγδ", "αγγδ") // 1
sz::edit_distance_utf8("façade", "facade") // 1

Quick Start: Swift 🍏

StringZilla is available as a Swift package. It currently covers only the most basic functionality, but is planned to be extended to cover the full C++ API.

var s = "Hello, world! Welcome to StringZilla. 👋"
s[s.findFirst(substring: "world")!...] // "world! Welcome to StringZilla. 👋")    
s[s.findLast(substring: "o")!...] // "o StringZilla. 👋")
s[s.findFirst(characterFrom: "aeiou")!...] // "ello, world! Welcome to StringZilla. 👋")
s[s.findLast(characterFrom: "aeiou")!...] // "a. 👋")
s[s.findFirst(characterNotFrom: "aeiou")!...] // "Hello, world! Welcome to StringZilla. 👋"
s.editDistance(from: "Hello, world!")! // 29

Algorithms & Design Decisions 📚

StringZilla aims to optimize some of the slowest string operations. Some popular operations, however, like equality comparisons and relative order checking, almost always complete on some of the very first bytes in either string. In such operations vectorization is almost useless, unless huge and very similar strings are considered. StringZilla implements those operations as well, but won't result in substantial speedups.

Exact Substring Search

Substring search algorithms are generally divided into: comparison-based, automaton-based, and bit-parallel. Different families are effective for different alphabet sizes and needle lengths. The more operations are needed per-character - the more effective SIMD would be. The longer the needle - the more effective the skip-tables are. StringZilla uses different exact substring search algorithms for different needle lengths and backends:

  • When no SIMD is available - SWAR (SIMD Within A Register) algorithms are used on 64-bit words.
  • Boyer-Moore-Horspool (BMH) algorithm with Raita heuristic variation for longer needles.
  • SIMD algorithms are randomized to look at different parts of the needle.

On very short needles, especially 1-4 characters long, brute force with SIMD is the fastest solution. On mid-length needles, bit-parallel algorithms are effective, as the character masks fit into 32-bit or 64-bit words. Either way, if the needle is under 64-bytes long, on haystack traversal we will still fetch every CPU cache line. So the only way to improve performance is to reduce the number of comparisons. The snippet below shows how StringZilla accomplishes that for needles of length two.

https://github.com/ashvardanian/StringZilla/blob/266c01710dddf71fc44800f36c2f992ca9735f87/include/stringzilla/stringzilla.h#L1585-L1637

Going beyond that, to long needles, Boyer-Moore (BM) and its variants are often the best choice. It has two tables: the good-suffix shift and the bad-character shift. Common choice is to use the simplified BMH algorithm, which only uses the bad-character shift table, reducing the pre-processing time. We do the same for mid-length needles up to 256 bytes long. That way the stack-allocated shift table remains small.

https://github.com/ashvardanian/StringZilla/blob/46e957cd4f9ecd4945318dd3c48783dd11323f37/include/stringzilla/stringzilla.h#L1774-L1825

In the C++ Standards Library, the std::string::find function uses the BMH algorithm with Raita's heuristic. Before comparing the entire string, it matches the first, last, and the middle character. Very practical, but can be slow for repetitive characters. Both SWAR and SIMD backends of StringZilla have a cheap pre-processing step, where we locate unique characters. This makes the library a lot more practical when dealing with non-English corpora.

https://github.com/ashvardanian/StringZilla/blob/46e957cd4f9ecd4945318dd3c48783dd11323f37/include/stringzilla/stringzilla.h#L1398-L1431

All those, still, have $O(hn)$ worst case complexity. To guarantee $O(h)$ worst case time complexity, the Apostolico-Giancarlo (AG) algorithm adds an additional skip-table. Preprocessing phase is $O(n+sigma)$ in time and space. On traversal, performs from $(h/n)$ to $(3h/2)$ comparisons. It however, isn't practical on modern CPUs. A simpler idea, the Galil-rule might be a more relevant optimizations, if many matches must be found.

Other algorithms previously considered and deprecated:

  • Apostolico-Giancarlo algorithm for longer needles. Control-flow is too complex for efficient vectorization.
  • Shift-Or-based Bitap algorithm for short needles. Slower than SWAR.
  • Horspool-style bad-character check in SIMD backends. Effective only for very long needles, and very uneven character distributions between the needle and the haystack. Faster "character-in-set" check needed to generalize.

§ Reading materials. Exact String Matching Algorithms in Java. SIMD-friendly algorithms for substring searching.

Levenshtein Edit Distance

Levenshtein distance is the best known edit-distance for strings, that checks, how many insertions, deletions, and substitutions are needed to transform one string to another. It's extensively used in approximate string-matching, spell-checking, and bioinformatics.

The computational cost of the Levenshtein distance is $O(n * m)$, where $n$ and $m$ are the lengths of the string arguments. To compute that, the naive approach requires $O(n * m)$ space to store the "Levenshtein matrix", the bottom-right corner of which will contain the Levenshtein distance. The algorithm producing the matrix has been simultaneously studied/discovered by the Soviet mathematicians Vladimir Levenshtein in 1965, Taras Vintsyuk in 1968, and American computer scientists - Robert Wagner, David Sankoff, Michael J. Fischer in the following years. Several optimizations are known:

  1. Space Optimization: The matrix can be computed in $O(min(n,m))$ space, by only storing the last two rows of the matrix.
  2. Divide and Conquer: Hirschberg's algorithm can be applied to decompose the computation into subtasks.
  3. Automata: Levenshtein automata can be effective, if one of the strings doesn't change, and is a subject to many comparisons.
  4. Shift-Or: Bit-parallel algorithms transpose the matrix into a bit-matrix, and perform bitwise operations on it.

The last approach is quite powerful and performant, and is used by the great RapidFuzz library. It's less known, than the others, derived from the Baeza-Yates-Gonnet algorithm, extended to bounded edit-distance search by Manber and Wu in 1990s, and further extended by Gene Myers in 1999 and Heikki Hyyro between 2002 and 2004.

StringZilla introduces a different approach, extensively used in Unum's internal combinatorial optimization libraries. The approach doesn't change the number of trivial operations, but performs them in a different order, removing the data dependency, that occurs when computing the insertion costs. This results in much better vectorization for intra-core parallelism and potentially multi-core evaluation of a single request.

Next design goals:

  • Generalize fast traversals to rectangular matrices.
  • Port x86 AVX-512 solution to Arm NEON.

§ Reading materials. Faster Levenshtein Distances with a SIMD-friendly Traversal Order.

Needleman-Wunsch Alignment Score for Bioinformatics

The field of bioinformatics studies various representations of biological structures. The "primary" representations are generally strings over sparse alphabets:

  • DNA sequences, where the alphabet is {A, C, G, T}, ranging from ~100 characters for short reads to 3 billion for the human genome.
  • RNA sequences, where the alphabet is {A, C, G, U}, ranging from ~50 characters for tRNA to thousands for mRNA.
  • Proteins, where the alphabet is made of 22 amino acids, ranging from 2 characters for dipeptide to 35,000 for Titin, the longest protein.

The shorter the representation, the more often researchers may want to use custom substitution matrices. Meaning that the cost of a substitution between two characters may not be the same for all pairs.

StringZilla adapts the fairly efficient two-row Wagner-Fisher algorithm as a baseline serial implementation of the Needleman-Wunsch score. It supports arbitrary alphabets up to 256 characters, and can be used with either BLOSUM, PAM, or other substitution matrices. It also uses SIMD for hardware acceleration of the substitution lookups. This however, does not yet break the data-dependency for insertion costs, where 80% of the time is wasted. With that solved, the SIMD implementation will become 5x faster than the serial one.

Random Generation

Generating random strings from different alphabets is a very common operation. StringZilla accepts an arbitrary Pseudorandom Number Generator to produce noise, and an array of characters to sample from. Sampling is optimized to avoid integer division, a costly operation on modern CPUs. For that a 768-byte long lookup table is used to perform 2 lookups, 1 multiplication, 2 shifts, and 2 accumulations.

https://github.com/ashvardanian/StringZilla/blob/266c01710dddf71fc44800f36c2f992ca9735f87/include/stringzilla/stringzilla.h#L2490-L2533

Sorting

For lexicographic sorting of strings, StringZilla uses a "hybrid-hybrid" approach with $O(n * log(n))$ and.

  1. Radix sort for first bytes exported into a continuous buffer for locality.
  2. IntroSort on partially ordered chunks to balance efficiency and worst-case performance.
    1. IntroSort begins with a QuickSort.
    2. If the recursion depth exceeds a certain threshold, it switches to a HeapSort.

Next design goals:

  • Generalize to arrays with over 4 billion entries.
  • Algorithmic improvements may yield another 3x performance gain.
  • SIMD-acceleration for the Radix slice.

Hashing

[!WARNING] Hash functions are not cryptographically safe and are currently under active development. They may change in future minor releases.

Choosing the right hashing algorithm for your application can be crucial from both performance and security standpoint. In StringZilla a 64-bit rolling hash function is reused for both string hashes and substring hashes, Rabin-style fingerprints. Rolling hashes take the same amount of time to compute hashes with different window sizes, and are fast to update. Those are not however perfect hashes, and collisions are frequent. StringZilla attempts to use SIMD, but the performance is not yet satisfactory. On Intel Sapphire Rapids, the following numbers can be expected for N-way parallel variants.

  • 4-way AVX2 throughput with 64-bit integer multiplication (no native support): 0.28 GB/s.
  • 4-way AVX2 throughput with 32-bit integer multiplication: 0.54 GB/s.
  • 4-way AVX-512DQ throughput with 64-bit integer multiplication: 0.46 GB/s.
  • 4-way AVX-512 throughput with 32-bit integer multiplication: 0.58 GB/s.
  • 8-way AVX-512 throughput with 32-bit integer multiplication: 0.11 GB/s.

Next design goals:

  • Try gear-hash and other rolling approaches.

Why not CRC32?

Cyclic Redundancy Check 32 is one of the most commonly used hash functions in Computer Science. It has in-hardware support on both x86 and Arm, for both 8-bit, 16-bit, 32-bit, and 64-bit words. The 0x1EDC6F41 polynomial is used in iSCSI, Btrfs, ext4, and the 0x04C11DB7 in SATA, Ethernet, Zlib, PNG. In case of Arm more than one polynomial is supported. It is, however, somewhat limiting for Big Data usecases, which often have to deal with more than 4 Billion strings, making collisions unavoidable. Moreover, the existing SIMD approaches are tricky, combining general purpose computations with specialized instructions, to utilize more silicon in every cycle.

§ Reading materials. Comprehensive derivation of approaches Faster computation for 4 KB buffers on x86 Comparing different lookup tables Great open-source implementations. By Peter Cawley By Stephan Brumme

Other Modern Alternatives

MurmurHash from 2008 by Austin Appleby is one of the best known non-cryptographic hashes. It has a very short implementation and is capable of producing 32-bit and 128-bit hashes. The CityHash from 2011 by Google and the xxHash improve on that, better leveraging the super-scalar nature of modern CPUs and producing 64-bit and 128-bit hashes.

Neither of those functions are cryptographic, unlike MD5, SHA, and BLAKE algorithms. Most of cryptographic hashes are based on the Merkle-Damgård construction, and aren't resistant to the length-extension attacks. Current state of the Art, might be the BLAKE3 algorithm. It's resistant to a broad range of attacks, can process 2 bytes per CPU cycle, and comes with a very optimized official implementation for C and Rust. It has the same 128-bit security level as the BLAKE2, and achieves its performance gains by reducing the number of mixing rounds, and processing data in 1 KiB chunks, which is great for longer strings, but may result in poor performance on short ones.

All mentioned libraries have undergone extensive testing and are considered production-ready. They can definitely accelerate your application, but so may the downstream mixer. For instance, when a hash-table is constructed, the hashes are further shrunk to address table buckets. If the mixer looses entropy, the performance gains from the hash function may be lost. An example would be power-of-two modulo, which is a common mixer, but is known to be weak. One alternative would be the fastrange by Daniel Lemire. Another one is the Fibonacci hash trick using the Golden Ratio, also used in StringZilla.

Unicode, UTF-8, and Wide Characters

Most StringZilla operations are byte-level, so they work well with ASCII and UTF8 content out of the box. In some cases, like edit-distance computation, the result of byte-level evaluation and character-level evaluation may differ. So StringZilla provides following functions to work with Unicode:

  • sz_edit_distance_utf8 - computes the Levenshtein distance between two UTF-8 strings.
  • sz_hamming_distance_utf8 - computes the Hamming distance between two UTF-8 strings.

Java, JavaScript, Python 2, C#, and Objective-C, however, use wide characters (wchar) - two byte long codes, instead of the more reasonable fixed-length UTF32 or variable-length UTF8. This leads to all kinds of offset-counting issues when facing four-byte long Unicode characters. So consider transcoding with simdutf, if you are coming from such environments.

Contributing 👾

Please check out the contributing guide for more details on how to setup the development environment and contribute to this project. If you like this project, you may also enjoy USearch, UCall, UForm, and SimSIMD. 🤗

If you like strings and value efficiency, you may also enjoy the following projects:

  • simdutf - transcoding UTF8, UTF16, and UTF32 LE and BE.
  • hyperscan - regular expressions with SIMD acceleration.
  • pyahocorasick - Aho-Corasick algorithm in Python.
  • rapidfuzz - fast string matching in C++ and Python.

License 📜

Feel free to use the project under Apache 2.0 or the Three-clause BSD license at your preference.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

stringzilla-3.7.2-cp312-cp312-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.7.2-cp312-cp312-win_amd64.whl (67.6 kB view details)

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.7.2-cp312-cp312-win32.whl (62.5 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.7.2-cp312-cp312-musllinux_1_2_x86_64.whl (250.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp312-cp312-musllinux_1_2_s390x.whl (176.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp312-cp312-musllinux_1_2_ppc64le.whl (211.3 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp312-cp312-musllinux_1_2_i686.whl (192.4 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp312-cp312-musllinux_1_2_aarch64.whl (186.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (255.7 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (187.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (215.0 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (190.0 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (193.6 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp312-cp312-macosx_11_0_arm64.whl (70.3 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.7.2-cp312-cp312-macosx_10_9_x86_64.whl (73.1 kB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.7.2-cp312-cp312-macosx_10_9_universal2.whl (111.1 kB view details)

Uploaded CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

stringzilla-3.7.2-cp311-cp311-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.7.2-cp311-cp311-win_amd64.whl (67.5 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.7.2-cp311-cp311-win32.whl (62.5 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.7.2-cp311-cp311-musllinux_1_2_x86_64.whl (250.4 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp311-cp311-musllinux_1_2_s390x.whl (176.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp311-cp311-musllinux_1_2_ppc64le.whl (211.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp311-cp311-musllinux_1_2_i686.whl (192.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp311-cp311-musllinux_1_2_aarch64.whl (187.2 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (255.1 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (187.4 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (215.5 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (190.4 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (193.6 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp311-cp311-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.7.2-cp311-cp311-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

stringzilla-3.7.2-cp311-cp311-macosx_10_9_universal2.whl (110.9 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

stringzilla-3.7.2-cp310-cp310-win_arm64.whl (60.7 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.7.2-cp310-cp310-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.7.2-cp310-cp310-win32.whl (62.5 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.7.2-cp310-cp310-musllinux_1_2_x86_64.whl (248.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp310-cp310-musllinux_1_2_s390x.whl (174.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp310-cp310-musllinux_1_2_ppc64le.whl (209.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp310-cp310-musllinux_1_2_i686.whl (190.2 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp310-cp310-musllinux_1_2_aarch64.whl (185.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (252.9 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.1 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (212.8 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.2 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (191.3 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp310-cp310-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.7.2-cp310-cp310-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

stringzilla-3.7.2-cp310-cp310-macosx_10_9_universal2.whl (110.9 kB view details)

Uploaded CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

stringzilla-3.7.2-cp39-cp39-win_arm64.whl (61.9 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.7.2-cp39-cp39-win_amd64.whl (67.6 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.7.2-cp39-cp39-win32.whl (62.5 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.7.2-cp39-cp39-musllinux_1_2_x86_64.whl (246.7 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp39-cp39-musllinux_1_2_s390x.whl (173.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp39-cp39-musllinux_1_2_ppc64le.whl (207.7 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp39-cp39-musllinux_1_2_i686.whl (189.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp39-cp39-musllinux_1_2_aarch64.whl (183.9 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (251.6 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.4 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (187.1 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (189.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp39-cp39-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.7.2-cp39-cp39-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

stringzilla-3.7.2-cp39-cp39-macosx_10_9_universal2.whl (110.8 kB view details)

Uploaded CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

stringzilla-3.7.2-cp38-cp38-win_amd64.whl (65.9 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.7.2-cp38-cp38-win32.whl (62.5 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.7.2-cp38-cp38-musllinux_1_2_x86_64.whl (245.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp38-cp38-musllinux_1_2_s390x.whl (172.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp38-cp38-musllinux_1_2_ppc64le.whl (206.7 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp38-cp38-musllinux_1_2_i686.whl (188.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp38-cp38-musllinux_1_2_aarch64.whl (182.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (250.7 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.0 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (210.4 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (186.1 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (189.0 kB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp38-cp38-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.7.2-cp38-cp38-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

stringzilla-3.7.2-cp38-cp38-macosx_10_9_universal2.whl (110.8 kB view details)

Uploaded CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64)

stringzilla-3.7.2-cp37-cp37m-win_amd64.whl (65.9 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.7.2-cp37-cp37m-win32.whl (62.5 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_x86_64.whl (244.4 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_s390x.whl (170.5 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_ppc64le.whl (205.0 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_i686.whl (186.8 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_aarch64.whl (180.7 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (249.0 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (181.5 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.6 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (183.8 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (187.2 kB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp37-cp37m-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

stringzilla-3.7.2-cp36-cp36m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.7.2-cp36-cp36m-win32.whl (62.5 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_x86_64.whl (243.8 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ x86-64

stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_s390x.whl (169.7 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_ppc64le.whl (204.5 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_i686.whl (186.3 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_aarch64.whl (180.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (248.2 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ x86-64 manylinux: glibc 2.28+ x86-64

stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (180.6 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ s390x manylinux: glibc 2.28+ s390x

stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.2 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ ppc64le manylinux: glibc 2.28+ ppc64le

stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (183.1 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ ARM64 manylinux: glibc 2.28+ ARM64

stringzilla-3.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (186.6 kB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ i686 manylinux: glibc 2.5+ i686

stringzilla-3.7.2-cp36-cp36m-macosx_10_9_x86_64.whl (72.7 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

Details for the file stringzilla-3.7.2-cp312-cp312-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 eb60e6e1249fa1522724d15f7b9a447cdb30bde7f463a88294025a57278f697f
MD5 310d2f487786cb77eb1337c3e2817484
BLAKE2b-256 8fdaa2c00ddf890e77d747b85fe298b87698481df06a32a94eb9923b117e4c52

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0fb8cf9d6833e1f1e02e2cfd33c15bfe87d2efaca0b8a6c2f860d19db22de41e
MD5 f1db2d3cabb6903515a5fce4005e826d
BLAKE2b-256 9ebfca2c5d7bc88bcb021400dc173c8e403d8f37a4fe7c0274d193a530d082db

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp312-cp312-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 8666c41aa785d49be90c2f46d118b5cef7ef219e07421c05b1b318248900d71b
MD5 9156ead7d78a1d8d12ceac7961eb21c9
BLAKE2b-256 0dd05d9b80d2f48945ed5cc516f540e78d4f93d3c4860e553e8dcc6a92e4bd47

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9ca80cb9b31274d92eacfe67c66416b48379a53c16e7e3bdee22e97336f1a0ec
MD5 da3cc01b87afb24b4e0f08905f1bd860
BLAKE2b-256 c1d0df2477d99e35cf97ada79f4d919a1b14b1d6957404cab8252153f92de3b4

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 8ccebd6f8e474006b9e5fc5ea3d291e36e8f8d73f66d75598475401a21ec7f2e
MD5 1085c46de1ba57431efd812d7e3e6a60
BLAKE2b-256 7530cc58fea70a41c695d75bb1091ad28b7d6614c66216b7d50fd72d7ca18f51

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 bc3bde433b4960657e4265f3486c966189cdaa24cc5266add1c5c402c9dfd65c
MD5 d50ca4c44f2149f1dbec8e160474e631
BLAKE2b-256 9431aa5065799f3f3ca229e1b57f93fd4eea0ead98c692884ec97c9bf7a5c050

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 4b580b1da0b84e03a75e8f3ba3eee23ff0f991c09f0449286adfc1d031ef8e9e
MD5 3d456e3249406b108b42be2fd69e6d2c
BLAKE2b-256 a29eb6da2f47b46e8135bd0e15b1810b3385923d7163b01fe6e380d3edc88938

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f9c93bd461f8aa8a24094d2229bbf155ab4bb334c070061a025faf4c3533ad92
MD5 a151f92cf0d724da710b5f1914f6a65d
BLAKE2b-256 e02609f09c538481e2ddb54e8a1a32e983ebc55a4243cba4a2a5b9b3ec13352b

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 68e600cf41548a74bd2dab9a38176a25019b4f43036b10ae25b216e9a415cad6
MD5 6e0c951b6116a90a73a9e81d97122460
BLAKE2b-256 384650d56332d7c0f731dd61a6e0abac4f46935227a20df75f93866d4dd3e007

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a8f4e32da2f6d6da3ad12acdafc68b9dd5e6e823f75c1d6a85dcfe4057d7f3e8
MD5 ebad01e55c2d72323be88af0c2aeb940
BLAKE2b-256 eac8444e3a2da6932f8345735772caba8e2a9f42c77c011ecdf9532a5452f38d

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 0849c8029b263016a44e6205c1d0a119aaa0353d964f67c3fa2ab8c5642ddc60
MD5 7aa9676b01fe9d843f78a36eb19245b8
BLAKE2b-256 71815ccce83f9887fc1dc81f431081ecc1f20bf5d97e456b18cae8e23be66411

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2d09a10adf99d4e1065ddedc82bb4945fdd6c6dc9b95801bba89beacec9dd497
MD5 8b76e8ebada8044283c205b1b2f29081
BLAKE2b-256 0958d749eaa3608739e83465d0f652a4439269e4230830b58cb8889c4e29e2a8

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 34289e106628dff9730cd8a3a0c5957513534af4e18b331be5a0c6e03117734e
MD5 f400e575a88821d36bd4f81122c44522
BLAKE2b-256 4f2716e77a1ade1810809b13272e4e427f3c8626a7255246476a901d032d143f

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9a15d917907ef99a4c0cde08cd7e8931b1ac195dfb9c16bdbf657ef7ebbc8298
MD5 02581ae7c729777706ddfea51e885ad3
BLAKE2b-256 3ede6d5d1f5ba9baa1a18ac6c5c7270e01cbece6158cb982cb35f683aa6c51e9

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 96e2d5d9a282b11661d63116f6a506c99d60a83c2c86d4c41feaf9f6d458397d
MD5 9415212a5d64c9279851be47f2c02ab6
BLAKE2b-256 8bb8fe4dcc67745b105a8f7c5997833fb7de85542747ebbb07b1d33637f865a0

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp312-cp312-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 cdf689854ed540576cf5c8975e2759f425431ece85fa3a034e3185937a85c1b4
MD5 75664771d94906238e01f40782aaa63c
BLAKE2b-256 b2d7a4c9b8cdbc4dbeb48e6a9a48ea39a1a19704934da05574746a965924b2cb

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 deb5cd7c86c4972339a4440e6c0d5fecd387cbab75487934ae373084b42473ed
MD5 af266c49656e2a9038da3cf49c9b0912
BLAKE2b-256 17d19ef96bba407a5b142633257ec7b1de4adf15248b183fc6312a8dca88a6c8

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 7ffaa519d0ae166b27b313e0e9578b01bf8143532110d7d38ead7977852798a9
MD5 d923e7070f1cf36d70e8bfc9e46f5d2f
BLAKE2b-256 f335f76cdaa2b552b3ee7fc36ea63c8eb2dedb7c6ee3c61c37015b8f1c6d393b

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp311-cp311-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 9520d4fd312eeaa7ed32e30827619a14cfb16a5012df35bce4105f23d1c5b35c
MD5 911563039a79d87fa29a4cca44a0ca45
BLAKE2b-256 84cba2168b0ba560a1dc7a09376631cdbed8af43f76ed23961c03461983f4910

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 94f21a7a45bbcae5afc0b13f78fb2adf037c887179517e4ee9b49d2db7470f40
MD5 d6fe91ab8b7ed3242a6b0a34ec605d1b
BLAKE2b-256 1900fd8eceace29a81b289156325c0859b134d884fdf92d64a6688bf5be96de7

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 502b3826a5c7598a4c964fc10d46034d3c44dbef0fd49e79151665974e9e4feb
MD5 4685332124640cfb36085e898683feff
BLAKE2b-256 48b13dac09e0c2b8e50e4ec7674371c3d77a2178013347072ad6d41275a9996d

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c52ce5cc7cf7147de359cf0abc28045b345a2d98440f59639913048cecf7e11f
MD5 2478e12c49f9ab2ba83eec0802d63418
BLAKE2b-256 efada360ad5ccee2800c3e581ebc299c4eb810cfe2da6af65cecd3c7c42abb54

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 dbc1c766c54fe8f39aaf08342fb2813b900e899d77e985b5e0543b4987c2bf7a
MD5 1c31e7208e5f418b2b8cb6a807cec261
BLAKE2b-256 f680cc5aae42d90aa0fd05bd003a2b0c2e8f066411894f7645b2102655286775

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 28347af0e467e81b1c16eb52aeb08529c76c6b5b50d51a4ac7b6d89e8a442472
MD5 47e442c43f8cb71715629ef9cb6185dc
BLAKE2b-256 3f21df556e7823b3102ddcb69083c9eb208f1ce4990f36bffa4abd759eb05ea2

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 01d34347ae11e216bd23ca3999bea0a8f000acd9c501937e86a1f47ff4329367
MD5 e3ae10b91776a9192c420c45156e7671
BLAKE2b-256 54d17af48ee48e1e12049e2e172b1eb4a1819856cdf8d692751fa444a3c1a4f3

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 aa2218a0aea589c5992c2ce74e166060e300549d4cf6ca135650a4aff44fac8e
MD5 d2830b1079caffda3d0a507f428a4e88
BLAKE2b-256 a678ddc311164e171694a85b15af03c392064e9484ce0e5119a9db079d8fb5a3

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 b8d8869ce630faeb1f8f699ef88b204406f6052d8e11c3cf6c8d8b8cad2a01f7
MD5 1b67de857e5b8c4b940d8c3b9bb604aa
BLAKE2b-256 7e71b9c852178ca8c67227d684682865b3447b4ce369c9fb6e87b2cfdc491216

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 189fe7619582e0a2da1ba00f733e33054c6a78808c79fe1d229075e45b431fd8
MD5 5ac0a4643204b341d9d32272a40dd58f
BLAKE2b-256 d7a9bc8536929153ecab98c968186cfdb8bbf5f48fd5310f75a5423109310743

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 eb708ca05e80ec5931bdc9e428834c44759e7cb34431812330c99bbf42442fd5
MD5 10a8f002a7184c7cce730231e8df1c53
BLAKE2b-256 8603f0c548e13c6d8fa8a2870d8601da250b7638b9ae1d509ffecf0c5d852fae

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a347f4edb7a74a802af3e73f006fda4497590583d73a398eb3f8a1c618ca4a33
MD5 b52ebcf27c395be75314c6859aa2128b
BLAKE2b-256 d442601b60956c345a2073072ebe3ac163b9daf7183896e6b569284786aa394f

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 b54713d83f78b9dace8d060f434be557923ef29f31d337936aba9826ff04bfb0
MD5 600ffe124bc776dbaba9a9f71fcd7c13
BLAKE2b-256 5bc87408c5cab1960c481d99c305462eaed9f2829ea244914cf025e12b3abd2e

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 fb4c3687440c8c5290d34e8e316621767e8d6e8545126df354e507685f90cdd9
MD5 1aa3716c729775886006e52bb2b0b846
BLAKE2b-256 a16687ecafded2596c6a4a3ae06d2ee54440d6c3238aca813e3fca7199b555b3

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 8a21c6069b8a0a6e97e5f879281f782747c264a731d1e371ccc120488b395865
MD5 49f72df5880012986b2eb2f9c7475956
BLAKE2b-256 daccf75c45e663e226dab7376d0b8b243cb1ff48a7efa42c7a047c22ae5d86f2

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 2b522b477626c46cfa3aa4271010468f37cb75d437eb3fff73c9afe471e9af5e
MD5 dca186a360ef78e14c994bd6a1f6adab
BLAKE2b-256 d1504e2f01d2fecd9185f1c3223c624e9510b1d86051049bd26781ed3c391fbb

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp310-cp310-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 7f1831840fbf4b381ef7a89798ec3278281977ae7ab40d13d55ef245bbdf8347
MD5 ed9a84b3e2ea57cbf5202b8e748c8152
BLAKE2b-256 01096aa7b23980cfe8519a0e1c96b4c3e155aa827997267820c4ceffed1155ee

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a7adf45d0e07a94b0bd134684e1175d58dba21d1a8f9a7a383649f7f35a6c7d9
MD5 26a9fd9e6708a45d6b6e7d8eec11fc76
BLAKE2b-256 c44455e5cb2619a93ba1b787e49e00d564dae3b866474a48cded6cfb0577e5b0

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 03bfbda4cff0a23cc1578edbe654584cbc0ea6fe61d9559fd70c078566b139a7
MD5 2f2f56d8add441aebcdd1da2faa69c3f
BLAKE2b-256 dd2d8d2183d7eeaaa49f9645c56d1ad09d8820e7d0020256758f8e8b455fe633

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 9d9c3f0a880ac335d562f5bda15a3875c406af5db3b9f114bf468b30e2a1b0bb
MD5 7923251c4cd569d954841631e8473ed1
BLAKE2b-256 941a83e278163bb9d60efaacc5fecaff802af7a8d979e07198dac8054f8d861a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 3015416833cc38fd832205370a6b346cd15d4f91efe08e6a2547129ec0398e81
MD5 efdbb77348eb78a8178b7b7306b6290a
BLAKE2b-256 6b4b3e6c36b29f191be266e312c5b4a17d93623c11a263e8186c848a4dbec291

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 7e294a6d70331ab433bd27dc15e140635a0def64b30bcb08e10d406c2f0ca5bd
MD5 b2000b878707b9e88620e4ef97b7e539
BLAKE2b-256 ce2e4523c0ffa8775a4965bf13113abda23a7741752e22be35c89865d88b21c2

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 162d233fa2da09db7a193fb76aa8e977d5bb53efbe6579b07f9db59fb255bcc4
MD5 6042ea7978d4a5a39772384961737ad2
BLAKE2b-256 48dfc608b9d2d51c5ed453c5c4c0cb60fe4a78755fba547a1a535a2500767e01

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 74cf4899e3111d773025621bab5652672ca38fbf3688875e0360d8dcbe146d2d
MD5 1521485a9f66c8b4d29b8d212eff1e19
BLAKE2b-256 aa62af09593d0764b01e06bc206e41ab754b629960ced69ee12be9489248b1fe

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 bf95fa4a4502ec0807ec15047040fb46e31c57e7f7f7186ebf6018c92bd69f83
MD5 63f675926a059b4b7f4d381d6b353979
BLAKE2b-256 4473038a5aba608892878b36c39202fcbbc93ce705abbdd0e1601a22a5988c9c

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c0ced4e3925f0dcc9fcbaab5833c73a7ee63aba573a63cb326c8aab7192902dd
MD5 7108c6621c11d4fd74519645e0544e54
BLAKE2b-256 e17dac3df46157107a19ec5e28b65309bb45440f4bc580d064ecd24470949a11

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6d83b0be35211744720debc2e5d0aa0a2debc9f955093cfd0625d2335942740c
MD5 fad901fde007055d103f24f369ab76db
BLAKE2b-256 b7fa085a443c544ceecba3931517fd607641995dd40e08719a15fd62672962a2

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dd6cdbe52d6d4abe8a475f1ff7882ffa694b1aacb8202fec8e6ce5a21638f273
MD5 e6f213b53ab28e23d37a341ffd89e762
BLAKE2b-256 4c98fb3b1ea95985c8669c3820e911271c8044d1a25cad58a19d106977359c41

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 32e1c5ae8933976b54b44fe71a034c794401cbc77724492ea5b56f85e7083260
MD5 87222069654641d6b214102728f9b131
BLAKE2b-256 6e7ddb2050552b808525ce1cd36272644b07a10fe2ca138228affa7617598440

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 da2bed38d136100a79729646bce00c89edd2f7f5e3fec8df07478f77bc609ae8
MD5 bb3c3be58d4290fecfdcd0ad6d69cae0
BLAKE2b-256 a86a0717a0910f1333d5a8d5500e1710edb3cd987611b636c75599adcf5da139

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 038b3cd824e441a2dd73ee786341375c5d7a535817061c6430619b3f14578be3
MD5 d5cef58b3a8c72bed6c6f5beb20082a6
BLAKE2b-256 18c7b11e66e66d7ec3a7d98289bac6daca8e34d9026132a20cb19914d6abf9b7

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 da225f2a48a1b04b4ae20789b55b1bb174f78f0e22701b16c80c00b199063a5b
MD5 383fb7646b7f4e89fd70f86d5f6d2a5b
BLAKE2b-256 86734f0723e2106ad108f667bff3b4123377ccfe9247b4ea389c17ee58e7855c

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp39-cp39-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 a865d4fb2385e7d7bf9ff6d0f69439a82667c4b334073086c92fc9b4db67c3be
MD5 abef9b40e8bab26db7fe2b81847c3711
BLAKE2b-256 de4e523c51ac1655e1a3a08a48c3fff32a143003d5d98bf33cc8ac9065e4f665

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 72f3c1ff0372f9fa9968037d35c027f1b5a61abe2d6ffdab613cfa07f9019382
MD5 8a4a2dcdcf0b455f352d431febaaf964
BLAKE2b-256 6ad20b9214fb676d8a2ea6369e0220da3fff4a2a882179a2cf1c4848369edf35

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e3c22a48f97334c1294042db57fe95a5b75992c2fdb0240fa0f9d31d3d009442
MD5 2e56b135f65713a4ebd95d754cbb214d
BLAKE2b-256 93f0138c6ee5d5367cd7553a9f5bb24f84c8ccfb626750feea4d3a227ea60f27

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 0a91489a4d695528af55eca1a1718714b349924b62bd1bb4a1c990138b4f1b6d
MD5 bc903910d00237428122a1fd109dadb8
BLAKE2b-256 1d69dbb19d1cfff0f0722ea7d6010c02bc6ba1b127bab970d7986b0fd0f80c51

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 45c8c3b303fe655f1535610598b56a2a952cae5ae8212df66eff9b381671db73
MD5 ba789c1e2c27a7ec2772eb5614bbed11
BLAKE2b-256 d4575de13c00bb8c8318c6f918b18b320c23d5f794c54ed9e25034be7d9d16ac

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1cff19150693d07916ae157dd0a380480ce3aadbe38773df95f95032174b149f
MD5 396ed5e527ad8045f64379c0ecb290d3
BLAKE2b-256 74f477055f7a17e7c676021da7678469ef670e67adc340e10128fb432833f2c5

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9d851725e3924d2c8508a17d749933451f3f37a33992d1ed4f9ea22c974b1178
MD5 966f4edd4f81b9f5e11d8352db6fd3d5
BLAKE2b-256 70228a8ebfaee21e95376052ae96592a2b0126ae1dd32e685860718bb85d4531

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 52ee75ced8f8c20c6b21d7922d9aa392dea1567581c22667464692fff8ead85c
MD5 dad5d52794beba60e5e29a031ae135a0
BLAKE2b-256 6d2e3d9f12049f9536be4fba4a613e9d18f8f5de8204d5e634833493b9f0b1ed

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 a7840bfaeae8a3cb814e6baa51f71d42df3f76f4969663ef3e819ee4d7fd61d0
MD5 44c5310b10ea222e3af5d4f814460787
BLAKE2b-256 6cddb64e33ed98a63c97747ebbf885672a3e98aab9ef9c595bf3bfd41dc33072

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bf03a78827b43ff868e05fcb7866bc144a607b9a1d6913403954082aacb9b68b
MD5 3bb6f0fbeacf1670636117efb5d0b98d
BLAKE2b-256 e762abb6352180ba2afc4043ff91a49d1e559ce4f9a03f79757053cb4b41815a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 caf32b39bb2424c8c802910cd9c443698df59811264c318712bfb12c52cf471d
MD5 274e3bb6449a40dd0e913cc2abc611da
BLAKE2b-256 604833ad0b7adce1502ce6a87a53ceac3976fb106447a1906f569bda74decddb

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 66d593702bdf29f3bc6ea8e5c96b9822bd831ad058260b145769c47496f413b2
MD5 ac309d7a1fc6c7492b0de3f31e4cb2be
BLAKE2b-256 edcfade793c70269f1332b92106ff92133b1e589f9da4bf3c2b24e89936b801d

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 104415fb9dd7e5f956c9f5c8cbf83ffacb2b481c012fe30cdcf8bcc1fb92e4ab
MD5 8246785e4db498bed1a895a6cd5ce032
BLAKE2b-256 74e28c8d10dcaa25fb34d9ab401b31220cb238ea5b269ecd992796bdf59cb2ab

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp39-cp39-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 7d2175a66fb5012cb38060943585adb35b327d876b9b82c4cca6e22f41d094ef
MD5 fbca146de3662e664376bfa2568af504
BLAKE2b-256 e09240e4e1328e34569e3c007b186a10807daf50d828a5188c9a71bc96469553

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 1ccc2acb8d65c20ab2312c5867f9529d0cb31d3e49f40abb8e9edf2b8c43e93d
MD5 a0653cc579947fc5c94dc87e255dea27
BLAKE2b-256 91c06e170af87b157d5e9dec5fc903b6ccf1c521957a67fa871bbc19751c5406

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp38-cp38-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 8bdae99411a5e5926dd6cd719675798f38aca1cf57ed40dbebbdb8ce5c057543
MD5 c301fdf4eec9891dbc097360e697e183
BLAKE2b-256 b8e64ed5e6864a74f54b0be0eec62acd5ebb24d90b215700227a32fef0113c59

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5f35a782197c6acc87cca001f7e543951f66d7b35aa1f59779a66f072acafc62
MD5 009d4ea540e1bf8fa1f9480edefdb04a
BLAKE2b-256 80fa3bfa5c7bf425d022578de884b16db26464389a3ac6950164f02690b59d49

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 cf747f073b3655932e186baeb028f8f5fd114c037171b980bab4795843a2d43d
MD5 2efaaddd28b659bc25988fdfded0d04c
BLAKE2b-256 a88abc5d33915aae434ef1a57665cb044e5f929eda9ccf151b9690d6e982a5b1

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 3287ccfcccc9f572498fbc814915e4840977b616742ad378ab3cd942129f09ad
MD5 554d5567b6e473ec30634b91c9553990
BLAKE2b-256 015cefb2ea78fc2ac586e73e917f35fe7d5691b174540efab75636e170667115

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 94f965abf09997c1cc46ca3bcad797c32baddd1f88934d55ac6a549cc739bd7d
MD5 9917324e8536d2cfe9b442c451ff4214
BLAKE2b-256 73487882872bbf31f7751335661dcb6cb6d43480ba3fd56a501da6e07c736768

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 04f56bb7a5eea613c6ba45ae56af8fe42279856e669963b0a68be6eaa86ce250
MD5 9da7cd515384265d5782c1d874d2480f
BLAKE2b-256 f36f91c9215ca560e0bffa3bde0a5817a76fed6669b25eaa00b65cbaa47598af

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3c32042d04fa8d066c07f5fe0177b12db73457c57f0f64cc781210ece13faf40
MD5 a7a83cd1d3a926a4a3eed733f3ea50e9
BLAKE2b-256 f4df33ae3db7c5959076dc875ad1b02cd4fca3c1cfe60db09141d378659fcd75

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 2e0516941319d3dac838124f3bd055107f1c3db85b71f129c96ba8fcf99b2f15
MD5 2ce15a10ac34791ada16dad6ee822b83
BLAKE2b-256 c39c24d503fe6b49eaa4b6cb3e50146b5eded6245966a9265486cbb57ffaea4d

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 17eb58c436e9c5c06d80906d566a3fcc4b4d8112dfa5d77b4ed8bb8982fce95e
MD5 090905aa595bc2bbf4935ee381f3f79c
BLAKE2b-256 791d6b8dbb73749bfede28b094358f24e05cb74c7efd2e4a6d7f94cece779ae5

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3d6e716b6d6eccbd67f1b8baadd4bb7fc75d76d2a5aa949d815d890e6f5c5188
MD5 f3a595462c62bd4815e74fba7b686e63
BLAKE2b-256 6a347590f0400d28ea48a5b01a6f89a273f8cdea4aaf8a589d5405283aa789de

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 639ce74a925013c3d355f50f4d794a5e01766c7c1e594dfe7905ad857628aff7
MD5 0463692e8e6ddefd84a78c4dc715b045
BLAKE2b-256 a546d4b69d42c7619361b464b9be2970bddaffdea074b12cc3a5d03acafe539a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 490e44c954a5d444823ece56f7e29a425d52f9f6d31119824ee951ca4e8f7abc
MD5 90c659afb52a88fc19347289eb8b5269
BLAKE2b-256 b8df4a8e8546c9eb3ea800c53d10fefcd14f44d500ade396fcc0919140d42cab

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 58aa20cd99f5929afe5508c326f8de5dc163440ca3d575c3ef6a5ce15ab31079
MD5 adfd9b9e1f9844c3669581985e841048
BLAKE2b-256 af99e602444a0d6b713b77b2839a6056acfce20639f126e04dc21fc4f08576ac

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp38-cp38-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b8fd705eeaac7d536255f134eabf0434266e0d9c967527357fb37e630a395aaf
MD5 64d5b597e5535b4836fdef600aae5073
BLAKE2b-256 26db1d1c99291f1352ee14c6cea4fe20339575cb13761d6a5a594259c0f0289a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 b8bda5152e3cfdf113a97857fd3b7617bb82ae06107ee73f161fbbcf94e5bd4f
MD5 fcff022c1388755f04796700ef5c7c26
BLAKE2b-256 3f435c364b2add4ac05270d9f572cd03e84b559541a9f525b4521215204bf146

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 03363b8ebb1ed4457cb8f617e1b43387bb69e3cebace4bab9fb4e72664081bda
MD5 86d60f653c70bc49cc9a457ddbd71535
BLAKE2b-256 1f9d4c7622fbd940070ca7a865b586f9694b05e9cf2cd9c188a089a2864d4146

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0ac786127ed604d82456c5698a3b1053d571ad5004bb69001e12876475a1c9a6
MD5 ec61127fb382183a9f32019916f00626
BLAKE2b-256 e75b025ede8c26e104a3e262601aff9f645fadd21ed960006ee56e43b1959e7e

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 8c1c0e22ee8e0682edb30a0aac2631523bb19f025eb87696be1b4f8d4aa160d0
MD5 76cff4771089ce77454f97e7b23a0efe
BLAKE2b-256 f0ba957dd3ebbcb0350776c5aec63b89dab0329609876862810422d4b85d6ca9

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 141d5530a6ca6ae848f097c523540cbad634c73753e10879c1627fe3bfbbf262
MD5 f71e648397378c3714e5fbeccb620b83
BLAKE2b-256 0cc4210b338c5a33f309b37662235bcc8b6285d54de2197116e1446712b278c3

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 5b3b47aa2f51c00ece7f898f9e1a299c45d3aa1b3b68f3096544d8f9e7238435
MD5 7b4f4a796e49023d764b7b451d972c26
BLAKE2b-256 a4475e0f9dfcc0c17248ce0d57cd6b98f89dbe21d3e5d34d7656411ecbf1ca20

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 af2cde2510a71dcd87d49fc25a3111302bcfef94d8e1432c136d7f9b35a2cb53
MD5 4c2dfa345b4dedc6d928913946757f1c
BLAKE2b-256 db825f06234c9cb12c78526e866f6974564c80b8cbd1cafcb9e593214caccc53

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 97bcf2cb5cd19cb4cf74065b0f484329643e39be76b5f0f0886c4b090ceb5d09
MD5 3bc8b6b0638af5451ffebe6a12198f8b
BLAKE2b-256 ef1958e9a2f7802934d2fbd59e0e31a60bad1bd763d097e1e5d14bb5bee275ea

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 602d93bba2b53dda5ed45dfe73a867923c4a5fdece0cdec9db9ab108b7150567
MD5 bbd66ea68fe061a49231c24da41375c6
BLAKE2b-256 e5c017f4dd8c021628ee08d578ca7c803131f6d835cf28ac5c54ecb8f587e3eb

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 abef9cc44a555427994c9b8de81e61d9b4b59e419a9fbec39f56bc741134b3bd
MD5 2fd2722d016bb509954d1b8bea15fd24
BLAKE2b-256 ae10ff1e3a27f33c7270af657f96ed906f7fedf6c3496cf62185b99b6b91d13e

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f33d5d0f072777a04983e0e884c6f9911abe74d8e7e7db0311ba1a3272a042b4
MD5 71ed08056467787b0aaaad1cc8831a16
BLAKE2b-256 8692d739715019216bd56dd226c80292dbd0d21bb09f279746b0f5c85bf92d5a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 caba3fcf90a353e76b04829ac4a935b1d990cdd1efbc9af73eae910bfbcb2a1b
MD5 6f97b433ff52df5e0354affdfd496afe
BLAKE2b-256 758ed239da3fba0efee191a1c8821a399163721e53133b28836c35f6bdc06c12

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2f741ee43a9bf44c076cf5982622a8e3bb927d7794e376e533e45b42624691c7
MD5 d14de1d9b862dddf3dab43a40b1b3c35
BLAKE2b-256 5266913c475c574b477f47224a71c79b941ed5f34015293895f9cc73db7e2126

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 241d187bcf87ac07aa9749d9b015dde3472bba9e6e8a52ffeaa613801f4fd7e0
MD5 60476c99cc43afd6f784ac8ae0a9b260
BLAKE2b-256 3acc8080a2d152b9b00189db10c65b6ec942d6ba75e58496a147211a21eb3176

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-win32.whl.

File metadata

  • Download URL: stringzilla-3.7.2-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.6m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 70347105bb15187c2f2ea2a2211a5abb7f31257f3e0224caff259ea6248283a9
MD5 0b5d18ed31d2400d3b94e2795d695788
BLAKE2b-256 e612f0a47d31a1b3c46de4378aac0e46c122bca92dd16b5454b510494661343b

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1ba6a9865be2cc6d130e666989a227ac2d59c71045a558b343902569bbf0f96d
MD5 05a5b71783a9d88e42a6dbcd0ebcd4d5
BLAKE2b-256 cb96fe893291443da2b5eb4d6c6ddbdbbfc00ff220ebc140fcb29f270750ff45

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 8779e8c5eaf2204a89fa9a6e7c2075847c43eb0cc16ef9e98b7346e2b7f3e8e5
MD5 780dce409b7f0daf718b085afdd37870
BLAKE2b-256 e4145c127e26caf128a8771d61fd0ade517bc98cdfd762ec7c21638d3fde9669

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 9383784621030be2409b66aee6b7b9d8d6810fc569ef7ff760a3cbeac31cfa41
MD5 51683af9401918c477c8db6e55af95e6
BLAKE2b-256 681b26df7efd3da686a467007ebc193b7ebe8ec7fd9a0001d207c9fbcad2f0f8

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 dab33c4103ae1a51e4850ef614f47d3823119a753c1ac0b351a41feb2c9e62a7
MD5 a620574c3016bb62c5c1b3f761a61fa0
BLAKE2b-256 5d852b2ba1d3eab9fad7bb8ff8219187f1998102d80c27b6de5ff535e871ae89

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 584f8446c99944e9cf85ffcda9ab9b794a1d438bec9bcbe7de7e1a1b6f0fff8c
MD5 a6b91c2fb549628177e02f13ac6ab1a2
BLAKE2b-256 21da3474c68062720ae5c06bf6f003ced6bf0991577b0ffc59644fb762655b41

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1ec1aa01b678683b2902b74130fa8e2516b1e495313aa86596676c1051748eb5
MD5 3d63e0f88c5e67e36c3f1114ef01f126
BLAKE2b-256 edd252ceb2eb084570475109535171f05d2c98952a1e7bf7c3d69d4dd1ecb252

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 4621dc3003150e01d9845e2db0fcae6451f02c0d64bbea0b5b35b5828ff2d4b7
MD5 aa4d492256b22895fde518142173fa1f
BLAKE2b-256 6a93d11661b5fa72ad53392ab4c7109a5e4ccf1b5b182ee7a9facfaf0ec21400

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fad6a9706f6383f782ab0eb0a499cf1b96c4a2634ce9c2a04664fad134b5673e
MD5 1199519f252a6f6dd5b7176166a9118a
BLAKE2b-256 61171742abefbb0e0f9903b9a9ed1fe619125c798d36f475535b22dc3d7e51b5

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e34b0a7da5a3636f427942c9ede81aa83389b69341407bb017ac679c7609a82a
MD5 d57ae054f7758f21e85666ae046b1432
BLAKE2b-256 0371a9ffe1369d42debb05d8406fe30e3633949958c0813e4ff74cc319948a6c

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0897297390192cd1f92feea22e31855edf32191a26993451dac81f2d728c6b98
MD5 a4c1a527eb3484f451dabacf77dcc424
BLAKE2b-256 94500d0d34fa9c66e79bdbe3f4752f687514a909e88472493a4b5c677a714059

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.2-cp36-cp36m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.7.2-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 8a2c09eb93de2d6bcd3c07449a04b66392be5ad447f1c8c937a79eb510a551fc
MD5 d1ac041f975a996f761edd005bb2ac90
BLAKE2b-256 a1e20a371f904178ec7d5d76c78f9deebb33f467a53acc49baf71214ac2cf121

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page