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, with documentation available on docs.rs/stringzilla. 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.3-cp312-cp312-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.7.3-cp312-cp312-win32.whl (62.6 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.7.3-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.3-cp312-cp312-musllinux_1_2_s390x.whl (176.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.3-cp312-cp312-musllinux_1_2_i686.whl (192.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (255.8 kB view details)

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

stringzilla-3.7.3-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.3-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.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (190.1 kB view details)

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

stringzilla-3.7.3-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.3-cp312-cp312-macosx_11_0_arm64.whl (70.3 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.7.3-cp312-cp312-macosx_10_9_x86_64.whl (73.2 kB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.7.3-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.3-cp311-cp311-win_arm64.whl (61.9 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.7.3-cp311-cp311-win_amd64.whl (67.6 kB view details)

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

stringzilla-3.7.3-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.3-cp311-cp311-musllinux_1_2_s390x.whl (176.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.7.3-cp311-cp311-musllinux_1_2_ppc64le.whl (211.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-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.3-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.3-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.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (190.5 kB view details)

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

stringzilla-3.7.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (193.7 kB view details)

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

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.7.3-cp311-cp311-macosx_10_9_x86_64.whl (73.1 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

stringzilla-3.7.3-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.3-cp310-cp310-win_arm64.whl (60.7 kB view details)

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.7.3-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.3-cp310-cp310-musllinux_1_2_s390x.whl (174.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-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.3-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.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (212.9 kB view details)

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

stringzilla-3.7.3-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.3-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.3-cp310-cp310-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.7.3-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.3-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.3-cp39-cp39-win_arm64.whl (61.9 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.7.3-cp39-cp39-win_amd64.whl (67.7 kB view details)

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

stringzilla-3.7.3-cp39-cp39-musllinux_1_2_x86_64.whl (246.8 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.3-cp39-cp39-musllinux_1_2_i686.whl (189.1 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-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.3-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.3-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.3-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.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (189.9 kB view details)

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

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

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.7.3-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.3-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.3-cp38-cp38-win_amd64.whl (65.9 kB view details)

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

stringzilla-3.7.3-cp38-cp38-musllinux_1_2_x86_64.whl (246.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.7.3-cp38-cp38-musllinux_1_2_ppc64le.whl (206.8 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (250.8 kB view details)

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

stringzilla-3.7.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.1 kB view details)

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

stringzilla-3.7.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (210.5 kB view details)

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

stringzilla-3.7.3-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.3-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.3-cp38-cp38-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.7.3-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.3-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.3-cp37-cp37m-win_amd64.whl (65.9 kB view details)

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

stringzilla-3.7.3-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.3-cp37-cp37m-musllinux_1_2_s390x.whl (170.5 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_i686.whl (186.9 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_aarch64.whl (180.8 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (249.1 kB view details)

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

stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (181.4 kB view details)

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

stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.7 kB view details)

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

stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (183.9 kB view details)

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

stringzilla-3.7.3-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.3-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.3-cp36-cp36m-win_amd64.whl (65.9 kB view details)

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.7.3-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.3-cp36-cp36m-musllinux_1_2_s390x.whl (169.7 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.7.3-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.3-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.3-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.3-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.3-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.3-cp36-cp36m-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 12e2419ed1df07b635642ffbc5cfc5e8f99525368c176509d0b51ed3f6e73f54
MD5 798c516bac8c5bf36f78855b0df4c688
BLAKE2b-256 826adaef11e21a345c827fcc5693f7336cacbe80f5fd531b987aa8828898310a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d77124deeca1b67bf70fc33880e43995f6cc88bae11d6f4805ea5d21339b7e2f
MD5 626c00f277d9efaaa3214108879a1f7b
BLAKE2b-256 dc5a915a1b8f8d15387ec1d1337277c59230d52af6c16d4a955181de506c2b5c

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 ae95451adadb7c861efe993a60c72d697fda0c753934d0fb7a6a5584f66aea4a
MD5 feedd6308262c132288435ef437975d8
BLAKE2b-256 a7fd2dc050daf954a9b20d4a66fb05a747aab090e9d2e73a3e5f068cc349644c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f63fda7184acfae52a016729a4c232e502f0d9df4c08b557b8faf8e900e9bd70
MD5 0b8deb8c0910aaf4e18dd548557af5d2
BLAKE2b-256 a62e9280efa896eb72b6cd3074d1b4e0b565eb9d4dd1777bb354c79861d2c885

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 22a836a9bfe3299e59201065c56b78065d36d1dc3ea2c74fc205a3fbd201e4c7
MD5 a6561e416208f0f4affaa8feb8782e9e
BLAKE2b-256 1faec6d93410f54399efdb35fa4bbf91b6e2066bc31179a162b3d7d3667f339e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 84ecad3d96019fb2702222b9dc9104fa6c265368d14052335f07a0f99135eedb
MD5 64d50c828f08fed420d7106ef39188e7
BLAKE2b-256 36151de869c303e29cee04fdc2173f0fbf15c5b748f3e1e077804f7aeeb5c81a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 d8efb81f7a86fbf8d454ac0869392cf6103a3bac8e102c01554a47d98c29252e
MD5 5dc1fbcdf930cb625ecde0cd72a2237c
BLAKE2b-256 a7b79e22ea7bdc0d69812e1fa5912f08cbc6c1481d64ddc217272dc85adb5887

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 eeb94e487f6f19aaec21cdbb3139e8478dfe4d7a389cb75be8b2ad671ddde243
MD5 9624fddf941af09f1f0445fd975c13e8
BLAKE2b-256 4235d9966814bcbca406d0abd44478095ac9641601de404c317d29783508d1a5

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b3a0e3475c9633470cb950e959ee43fb3b62f4785e3d34c73303a033b028bca
MD5 73fe26c92dca7315b304152e2dff7f3f
BLAKE2b-256 77e6d1ed3ea0190262c3fe991cb3b7d73ad3e9183da26332ffb5d57787f81da1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 e2791690f3115452bb05ab946c216ce7a9c89598f3eadfd333f5cb244765c163
MD5 1d93e81257cff505a4b3e7859c811474
BLAKE2b-256 5f6e61bc495b3dd4bbc8c831279cd44709f561f0ec24edb1d95c398607624dd4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 ecfdd8ff1b2b618b388d8ecee3df19e36f22dcd164466aa9dfc8ec05b4534938
MD5 dd8975235eac8853e7e86671396665ec
BLAKE2b-256 77a5f92aa43359881e1824d90f33b14371fb330fd5b3a10dc37edbcf2caafcdd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a074980446851e09ddac885c29e8e96baf3f4611f22f2648fe2e2f1443db82f4
MD5 7f1544717321e66838455cf49cf01c74
BLAKE2b-256 a19c59b7f4af8a3fd20e0e8aaed5ff671e25e40ecac3d206401177ea6cc049db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3b449aaea610c2cdd2a69d5b1b9fd1ef5aa6944f79a7a6d3d42b36f116988059
MD5 4de3d7ddc9970054bc3916c3463a3a46
BLAKE2b-256 1f591f4ca68a8afb0f93c9613a6a933a7ea025e10b01057c4657d52f9ec6ac44

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 36b2e53d0c9fc475a6b3ff349ba58b6ff3ce057934bcfc59666f45109efee516
MD5 521bdd2c72f7cdaa598cc43c1e12d328
BLAKE2b-256 a9ff99f2ff3db4cd9499b6ffcaa62213eb03a7e564be8d6a72e713fe1ef94fd5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 7055bde629df3927d39afae70652a06863d1ebc14dabce2106ab5e92d2517225
MD5 8bec84f25061c1827feb8e4b39b95968
BLAKE2b-256 f3c52a85bb937954787a0d7fb246f4627f40e61ebf3d1f7a79db217561aa0944

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 64548f42f46bb18e8375c0ed423a28d49e6a8ff41178778669007a5f8c4044bc
MD5 cb7f16f3f1ade99b3ead8c360f431378
BLAKE2b-256 58e7c8f7308236f4e3fe95ce91a6ff98bd3777197cfdbeaaaaea8698a3cc8cf4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 a4ab4a9a60374a7c6279f3899f31ecfd2d221fbf04f0495298d51df8329b5821
MD5 e9811f7a2de2ef1b4d0b43f2f9fd2972
BLAKE2b-256 cfaafdc56b5fe1b6dd93729d456a4fccd4612ec217e70f5045f15349a60dc73d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 da26cd5651bbc1997dcd07264a456d8157adb89e37f8400ca2370f3628b97c17
MD5 a0337d5f741ac624e78ea2ec613f772f
BLAKE2b-256 cde918a53c145a2cac8d2c1da3af9c1106bead81b3119bd6d33b119c58d2b254

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 d18d4d1b5a6f6473cde56dbb7dd4c094bd7b2a9deddbf9a8d34cf3b38d5838d5
MD5 a87ce2d5390c812cab06c0975c8da1f4
BLAKE2b-256 0d63065a7b8071ec344efa7b5390bb21bb6f9693f44423b206e26461348e4e09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4ec28230d98e4c17efd0161065ebc3e1b44b91f2cc1b78a3d1e55508d1b13d1d
MD5 32b3ea0684e4a4e871e95bdefe3c8c0a
BLAKE2b-256 34645bfa1eb65d2fc24db338eaf9ba62af962ec979902dd9536a76664635f56f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 bdffa5d8117173dc2c7e32cf6bf55b5a5732c7c3fd9803a8872657539e711fec
MD5 74c9b19860bde475e618a093beda9ccf
BLAKE2b-256 137b6381b0c1bb543df134a6ceb49fcfc02d63abc6a4deee70ca47db1d4fc1f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 392546cf24171906fdac30d1cf1f7d02b8843ba0059f751269fea9397e6f58da
MD5 b9b193f2f52cd51a59036c3e3e62a699
BLAKE2b-256 8e29d9cc0e38652f4d686160095204072788602c8b7e1f7e68a96c029973a2c7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 4358cea7b3321da1bd8b497a9d278f5f35cccaaaa7af54be7af60cfc4f71a2fd
MD5 dea5b793c11885231d6d531f71c7473b
BLAKE2b-256 2e6f1fa92ba05751dd4a8da97b165dcf218755c30104b36f014e3b2b716f9b42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4eb0307b7869c06a367796672f7876256fc4c02dd6997d9e846536c886ad8e0c
MD5 00844dae2a479388e15674a9e913b53f
BLAKE2b-256 9f83d54506cf1f613c87b5d381c71a80ccd6e7020e825f511c93eea52335b877

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9115f82cc94828feac83d1308bf090c91bf73f9890e2ef9d7a5b7de9043ad939
MD5 106dacf74da9d7244e76875d19328d53
BLAKE2b-256 713635dc39644f491c4822c1e4ab009802f9097e3d89be9bd7e7cf5c9327cb4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 f66ea4cbf4246c90755cf8b615ebe28caf6402e52eb89bcd8fc937f36fb4eeba
MD5 cf64b2e80e748fd9b2b67bd91731535c
BLAKE2b-256 c244667033d8a8d9e1177f7cb3fc173f03df481e40f8f858161f8d427d546803

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 333b35f5bb2cb76f2eddc8ba6a34c5f541e1caac6a0cceac89dc94e0c8e09356
MD5 a2bf9d6d8c112b1a376bf14cd93d78b3
BLAKE2b-256 277f72a8ba91454004bd43e5150d8c243ed9dd9a5e281af5e667b06d47a0b753

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b94de76b03c892f68445f6c5d506ac5afc0814f44829067a573135b54f370453
MD5 52da44dabb4b5641dcf510d5c649e153
BLAKE2b-256 7653fe995dcb6adc8cb0919b29fc3733ee131de90bf74f458e661fa886a26087

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 8fcdcb26c96321591b08b1c9672a29931aca479f127547ee7f2647db5c6560fb
MD5 e9c1b456e4936d8ca5a01fc376b6eb47
BLAKE2b-256 cc64a346bf5ca9ac109f5d04f6c991c00eaaf54bbc5d9f5adc94ca5160a2dd9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dcb6a805d5233679f759b66cc692ab0feb93ad0a4d1ce864dc3971d2342a3c68
MD5 3b0e428151afd0da79c623ec5ac2e1ce
BLAKE2b-256 134347c6bb292e2305a1c9e1627ceaf2976a135fc1d8a9f2e7c0dd4b644cbf79

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c6bea27e32ed214b6f7ceca6980798c86b74be3e1c5ab6a2d41088192e1d6453
MD5 995beb5e84bc9048908b5505bb2b028f
BLAKE2b-256 1947c249378ded0f80244ec70b6359bf8190fd729cdb2e11e999dda8d0d2f3f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 333e87f87bc792e323e0310b71ac9b1b3b4b2e486aeb75f4815525e87dce210e
MD5 4491bc9bf44aa8216930c3196ba41260
BLAKE2b-256 c5ec667c711c5f0077344690bd23c1266c71b32ecf27a84f79cc93c3a41ee5cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 d44bced3d613dfb858512710e1691085baef224e8fc55d55c9425205e55e7404
MD5 3b1e7951fcb90899849fdcfab828c791
BLAKE2b-256 2d322a189d96167fb8ea2045319cabbebdb1b171be54d08569137f0dc79ac20e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 7cd0bd5b3cadc86a7fa1a030e419dbb0ae44200889aae0afc1cd1a9076936296
MD5 bb5fd61ec3a221934cc2b8260f996610
BLAKE2b-256 e3d594331104db097625d8c371f4956e0fc24f39d1bcf309ec116ce29c590660

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 089813c4c8a3d7d4ce16db76dd1566e441ed24912cd3cad9dac91553f8b397e3
MD5 f9cfb73c07b375e5c0d95b817129bfef
BLAKE2b-256 ebf5bfdbf4f5955910d552eb025287776f67dad2dbce135f963a16b8b28752a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2c84158e8c264882a1d17a73cf98ddd13012f27fa15037cecd7ae14850c9c526
MD5 664638dfbf6a09374d1fd20f7820ca59
BLAKE2b-256 d555b01ae6fba22f0ec2141dc9b7e842644f1d5cec85ace1aeb2bd65f2da5ac1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 7b2d1412e866ff4b127f9f567515d3c77899f5e883901516db94b80888fe1f5b
MD5 0e626a79c64f52f37fd6b11490cbc27d
BLAKE2b-256 94cab657fb088f0a7d4ca075316fbc387b91bc77f413a9cdf5900a2d1f035a3c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 2321c9c0fc97bc0f2206b9683bcffaa79e86f8edcd004746bd07ca9c808b3229
MD5 c93bad933d6e9d5bb6644174405968f1
BLAKE2b-256 b6e9d104537344c03a905ca1c3088d05779810dc99bc8ea17116074149037261

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8b292fa283b2bf791b04ae76a4c69a98a44a3163db143a269f2babfc6c9518c1
MD5 ec6c28ee757ce63c170c88d8bf8c23fb
BLAKE2b-256 04193a80d29da03086704a2033825a0f6205833b325c916d1f2eade431323649

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a3709745279da67d90be14981255edfa397cd936ad83e200bd3c6e75afb9691a
MD5 33ebec1c0f59bc4a0d5a30f1f9cc0ceb
BLAKE2b-256 afee785d160e52d6cfbbc0c27093b2ce87d3a92f4d2948cbff4131411a6734bc

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 820d028e5f280818f739d95c9b4f5ad0906e4e5e136bde6202731cc44ea3f73f
MD5 a8f8d171ee222c6a1bc0d42a738d8964
BLAKE2b-256 ecab3d91cfa7f3b7de00bc4963b778dfa2258a86505fdaf3d4ee5c25ca6915b8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 0021809a969d0afc812a508c42e4b723feb9134a15a8a38dd430b948227d2d00
MD5 104e0a87680b780c61d5fc2620bdef80
BLAKE2b-256 a3100ca6c5845c817a444e0004d07b0f6bcfa7c8bb7b319dcd795d95b9d7016c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 09db216ff070b5bee6edd4a88c4b7ff3f1272c93e5acfdd66630a5b42af84279
MD5 c6a9dc5285ce9fc9a06b922a83403dc6
BLAKE2b-256 2318e7d46e4a4d7360d902f38a31a0dc7e712a6f58b5a97459d7600b6d87b8cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a8ca5bda39307c01147874c33ef9ed431237464f5d245a423611bf0da92d2e5b
MD5 81cece590455642351ebac0273c82004
BLAKE2b-256 4be274c13a176551dedee6d5b5a97d7e87f3eee9468adb2a2ee189d71bcf8f93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d0578b1dfe2b03e283e2f7b750ce7fb2605ea3505689dc6d06f8130e0394e110
MD5 78f1506db6773e6add53ee1631f7ba6f
BLAKE2b-256 950468380e79ba5e679888918474dc235442d133690db9c72be49cc06e19be93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c88c7062ad297ea7a80f8195bbc9a36393aec5324b1d0aa525d3e7c7be7c61fd
MD5 40254eee5b787306d6a52bcf9f2423fd
BLAKE2b-256 d36fe2f5b9c37c653d54bdc9184eb7a746d5fb9a8ba6b978a2416b9c2f537e9c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 8738b58578a393d7452fb90e1f485e76d9d525ec68d3eee978bbe26a57fa9505
MD5 65c7a3094dd90fb234266d474a708022
BLAKE2b-256 54a10e4ffe2b77697870c783ab8386a0146248cf93b52fc89280046a5e34e617

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 5cb985b7fab10559bf6d38c598ecc79a94de1505bfb9fcb595942a1d7ed669af
MD5 7437b148cef7abc433f91ca8607d9c7a
BLAKE2b-256 429abfd7312f06a3c1b8aaf538d632b0a0c0321cf3d0759f0418b33fcab0b7de

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 847b90bb95bd64071104a4748264606d376e03e8d627e2df090a2efb9a58fc99
MD5 d473149a3394e13857975a98186d396c
BLAKE2b-256 462b8c4e142f71ae79b7f97981c4ec92a7061dd9ccba274b943099f5a1ca9aa0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 feda5b75da579616e475fb8a8dd6809bec3b57bce65163727a28297bf12ed637
MD5 a0e8bc4a814f12c570bf7dca8d1f8f32
BLAKE2b-256 825d878f0f1d098113bed00e0e8d342789b2c1b16d1e3ff1a0114303a3b8f3f7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 c95e90a1f9b0fc7ea136ac688012cf3ae0cbbed13d8d1a9b990b88f66bae0a8b
MD5 67d7d2f4ea9de621325177d10eb70bd1
BLAKE2b-256 33421cf590a4f727d25185321d13fc6a1deae94f1d2aaa742076df2e466f1ae4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ebb43bdf2f0ea67242a27e3b1a1f135788cc9acf0de2807f483fd4cb3c48a12f
MD5 95d7edf1ffd911a28e33c8634a4c100f
BLAKE2b-256 611535a9fc62c644cd275ab5c3e1c46699ed01e39479a6724c434ee886ecadcc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a5c2746269105f89ed3edef19f19a68170e299e007aa4b68b84fb7e96ca2beff
MD5 9b004bb864af207a5987aa2d70070fe9
BLAKE2b-256 1aaf628869f97e57b4ec050d56c0e73ec5180ea0e1f561c269ddd76158b5ef5c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 7c4f0e9d3045482249adf7d0ed90f8ac2e2d5d2c9894864ded4040ad3da478fd
MD5 dab059f180664b1a02b5abd3e5a06418
BLAKE2b-256 a299ba0a397930737806f76b33c0a12ca41ecb1d4b8a2ecb01d33886c42fa952

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 b3aee0d231552668d2ecb2c5a7b0a045640542484d8b1e943235b6ec491bf49f
MD5 b11c474dbb795c0f8808a501ed50261f
BLAKE2b-256 2a23264b1821292597fe36f6b0a1275f9264ea3d59fe9627a79a8eb736f37023

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 30a9163af13d62e79a036eb8425908fea80011cc490706bb172b8bb8d37294e6
MD5 f31f9542ee5ef7802a86eea6870ada22
BLAKE2b-256 910288bc2495f7c01e2e7f9511975f3918f9f5f67eed2f9f522606e21d309894

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d838ef9144309b448d115199a3c9d3500ed9fbcbff923d8cec9dc4af9fb16809
MD5 1d52dc9868204541b5eaa665047fa9d8
BLAKE2b-256 22abb79bd2e8973dcbb59757632a432f88fcfa756cf080cee83b3c9f6bb96ebe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 61fbf476279a4abf347c3e111fe43b23862f4d82be278f9bd05dd84ffcfc1319
MD5 117da1f13c8c791d0abca83ab68c81c9
BLAKE2b-256 cd63ef9b8d40d120254dc7d9d8c4c7a2211b208724358202444d30517b9b3542

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fd62cec088b3bc33a4549141d6b7219a854cf1bdad3796f33533eed0783143a0
MD5 de9c8950be1474211f23d279ed43a67b
BLAKE2b-256 414a012ee683cb459cd05647a358915c9bd2868e7568ebcb742d8cc0ee7e6d92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5419d2ee574d85534d48246b1f04760cd1710e7efb30e4a5739a58ded68fbf4c
MD5 69bc94f1aa98ca5b5e8fbba3981ae84a
BLAKE2b-256 9d9a803b7aa58acc17e779c7c4514b28e6d129abdefd6f10d7ff25c36090d4e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1f3f1537ee32ac40fcd9f794352357665bd57e5cba6fa65a27aa037834d85cb0
MD5 b08fa27ec351a7148f4c8c8f7f83f4af
BLAKE2b-256 1eeabe47ace3de6a4d1920301e3565771bd63c8c736aeed00c082c2ea7bc55fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f7044329a08122a6c4132f6eb741bdf16e370030d024a5562daebb5c041a4bcf
MD5 03f3197b3103caf4a78a578d6e5e43da
BLAKE2b-256 79836b92685da4e8fb13972fb7bc15142c801b2fbdd6f783f8a01735fde0c1c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 0009410bc1c7b08912e34907ee92823747ad537f3997b20cc0b2645ff7c18d5f
MD5 4d09530d574998481bf5ccb327f9cab1
BLAKE2b-256 b3a1ff0fc2e846fc759b826a61d89fbe4495c1c6c21ed7b9e35c5d19da95a166

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 924ea1e7f7d4735b0a8d0c199c30929b4ced8f73100c36490a641b81cd1e8d85
MD5 41d2291734f4225208e90cfc18e8a104
BLAKE2b-256 422990075eda61ad6d4fc72796c3ad57ca1718d6757ccefc73e9494aa0f72d46

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 e76e17bd8f36f520953a502fbbc79f4541a65a6deb7567c476933722437d9699
MD5 01fb0bd8c6071384f1100ab1d691d1d6
BLAKE2b-256 b3858d1c1dca19b7c893eca09d707aacce02f6f706a994c475ce95ff7ccea9f2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 96abb885d8f8e795b517cb7bb116ea08fffaf8bf02fd2e9f04d1eeb4f1d1305b
MD5 601341ae99e389dab4e20dea6587f040
BLAKE2b-256 41f209cc541caf9fe3eebad08fba569b57b37dab8bca59c33948b68329c515d6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f5c4a373143bc6cf19a5d639493c4d93db90c4cbe98aeb4513cefdef69e0928a
MD5 ffa30f895e10f0f1e4d51ad067778545
BLAKE2b-256 ee8a7c77f6938a435dfca4496677039f679f7ceb14aa24b0ee58cf12a68fcf0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 9c899e131f39b01d1dca13c726ccc77203b30cabb5c51e713ba750208f994c3b
MD5 169f6395ae10c3e21281c31fbd950d6e
BLAKE2b-256 b0f2a9866d599179852bf8846db7e6e7fca7f497f2684f933821c2ff2f5b5d42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 71dcb7dd8b1c602f4ff3803e56d4c8285adbd49a1cdb0933d8f14baa9e156ece
MD5 f24887293fbc801ef37849539a0c55a0
BLAKE2b-256 a24ec65c7f16cee8a1d883ec1572453cf63c3610daa5d555c4f39fc74dbac528

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 58e86db6b26dbf189569945ab3f3b3fff0b70f094c92dbea6e0d99acf75a99e4
MD5 3519b66e02fee0d1ea44d304a720774d
BLAKE2b-256 15d96348b258f0533285d0fb0ce0bb5ab9292cfb0ba4aac649d0b729c9c0b6b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c07db3cdf5d879d2a614bac66f2e1236c3bd625db7dba34d8fb0a6a8af236e20
MD5 027c80ea492b21b94998041dade3d696
BLAKE2b-256 08a968d0768458df93b5fbf724d575f2903c7c591b1da678c5d5af15d1735156

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 12c8a5caf26d144ffc1545701ef5dcc80681353c8a42894e0248bbd9c39de98b
MD5 8694c5b6cfd48abc1f24ab2a11925d2e
BLAKE2b-256 ac79f54da9bf95cd5acc08dcf94f548f8845c0e9b286a41ae6d8f482332cf53e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 09332543857500baa3acb4149ea4a537fc4b06117e5da9a24076106f0c1deffb
MD5 370dfad686ed3bdfd38536bfe5ebe477
BLAKE2b-256 c1792a8a57439173ce1febea9a409d45035a607863a69c1568fe9327c52cfad2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 f20f89bca5aafbf15ca46620d82f9eda6da67e848146e780154b1c869f28af09
MD5 6d1783bff12732d6c0ee4a8535f5c842
BLAKE2b-256 da08b322bfeed42ffb69ad01535fd86091b235629ef047c71a08e11a59da8c10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9b0048042333f80f66511610321276e910665d8e5c4ff102a4cebdf3d9764064
MD5 564168f0ab6865b5284a5b54156f0e5f
BLAKE2b-256 44fdf383b087ff5b555477cf128c7059e75bcde3e23ccc6383e3c576c1a30e29

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 c4bf101bb1a1531b91d0351af2ea2988cfae3639c0de467187f464636d96f5f0
MD5 77bf43c12b84d58484cbdc40881b61d8
BLAKE2b-256 b0c0ebf6e5c5f303fbaa9463090bce26bf45b396aa6dc95adbb945279fb855a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8bdcca34380cf2d865dde71a36f9a80de74732941a17377fa00d4102dfb482c8
MD5 c88785448fb362d3acac3ee6cbc1fe13
BLAKE2b-256 3491a35ef0c81be71675c84a6cdcb5e49fd6dc076d16cca1956af256e8fb79ec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2b8cc84a47c62e2b0f8add0457f1bf662e4ca606fa0ad7a06387d68f37e7f7d8
MD5 7470010b3b32a463ecdcbe347c37ec75
BLAKE2b-256 54018b14c8d54c1f254516a99154a9971d6e7a0648446de5e14c8a67a20f7aff

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 bce3e39faab3ebebf12d38c4533846d8ce132110984e04b5a6c5ceeffd010f2c
MD5 0fde9e007510f2a1be789ad0f0c39ea3
BLAKE2b-256 f0c26f76482234b683ced66cc74b788f0d3e28e295404d88c8fb46c59e03aac9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 8feda6f57932336bd84a8c9f192622e3e437c77b96b4a1f21d4de60db0515792
MD5 423ec4214f18bf7bf7e464cc809aaad8
BLAKE2b-256 6da0727f5913afa447b18c8c093a1eae0b9dce5372fc68a6b703992966e926d2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 f8c840863e491c4032a98467362dd608ea0fd5615ad484a8cf20fbf1a48a5d71
MD5 84bc953ffcd6b8a4198bb1e86ae0840c
BLAKE2b-256 a98f7663c6a2648ae9b161a8f7c787a805a97d3b1cff6a888e1f33b9573b075f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d89bc26ceeeff64c056e57e9924da62054c2a50e787eea160178573413fbd424
MD5 cf586d759f4bad0b63b0087fd59ecd7b
BLAKE2b-256 00bb96857487121bf319d11df1a8d3084152433a19bc7e05efc6412dadc735a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b41fe43481bf62b9adc619853023f8158f3da89c95d828cec15994f2e5c83093
MD5 45925988854bfebe3fed9c7b59e6acdc
BLAKE2b-256 5628309a8b6aa6e16097850fe78aa9473477d77f12dd100898b824334e57264d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 e1df878bcb08d848ce2f5c646e3bc707857b78796e8e023d6ad3f7583d1b22f6
MD5 1606e895aff54c00420f7b0c213832ce
BLAKE2b-256 638d553c3b1924e514bbe4764bc932324a1657693f7e89e58c4a210f8b3cf960

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8f24ce184f3b624a52a63de04279d413a0232b3c1a682efdc62673611da038af
MD5 a4eb76dc6365e69a0a807cb5d5e2d05e
BLAKE2b-256 cb181f4e88b2f0cbef97c22954176fa8b074b6413ed16f7635684a571e433544

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 66386b4178d8fdacd2c1c39bde29ca02029356cc270c7a95542a379f426c6dcc
MD5 9f895e8428448111088f2db1c35f48b3
BLAKE2b-256 1455445a8fd13c8d13f16fe644049b89199073d3cea08e92468c4505d50b92c8

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7e32807a8d19598034350c09396fb66f31a3185e4ed95b856a15a7107c4266cd
MD5 740ebc735b6bcaa0dd6b5aa43b8b70a2
BLAKE2b-256 916511ea30b53f7c614c6cd6832d27bdd625cc9d706e0a4112b7f0051b7b62cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 963f8c1b46c84c6dfcbbb6ed4193d07617aca457f2f52bdc101b268867b7382e
MD5 80895f359e97b273c61ef43281f52bb8
BLAKE2b-256 2f957d601c4bc84105c668d18dfa4f05d3564899c75a61f3051c3c4c4bafb3fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 e1ebf47316b122527973e33a7a9065e21034ab0faf85f6f01741a21910438a5f
MD5 3d43bd283b4c5ded57ec901c583cf225
BLAKE2b-256 9dae6456a2dcb733836e874a748b997c9dd5f404dfb4031dcb63929aa044c57d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a9a5209120c75313fe3efb3c7f5937a2abb21f325965c9a4634959513c0be022
MD5 37d1a46f11771e4bc59eb0adf1ef317d
BLAKE2b-256 5ae0cdd5d36bcab8f35fe6c66d6c515b4daff34c76f0a215210b322acc3e146c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7a845e40a6897b4b670232a4fdbf36dbc38e631da2b672c83477ddb7d142ef11
MD5 dc6b1ea44d8a53b39522945c71f43314
BLAKE2b-256 b429182efc78ff9c6438a68ac001e18233cc452ffe12e6cd835673d47abaeb69

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c526e8a569daf65afb4a86133c390010a84cc88b48806cb84c7a1b5adf8787d6
MD5 8c3452d8a9d91ba484800175803a506a
BLAKE2b-256 c8055e8697f99e45aa58311b489380dc237211606e23bd1e16426d472ad4dd19

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 5fe75b6ab5ed5752366d764649b42a6a526a1f655a99a16a79b24a646520d151
MD5 77ff041d508213659377f9fbd71053b9
BLAKE2b-256 ad8b5d510e836d864a50989f33bf6403a171a306d2a84324233779112c46ef6d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.7.3-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.3

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 27e378030ecfcc73b9d4569fbca67455ce98bed96c524d484bacd0a0da5f06e4
MD5 d94deb351c6101462860a447a08fe12c
BLAKE2b-256 215854f06b53b1a3394197aa5cefc52552aa88dc618b97c52702262a6466e3ee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 16c1bba5dc4f2f74c9f9715c4b491936fb0bfbcf5824889ca4a46d38204149d9
MD5 3821b7ce8839d3fe265bb0a136647080
BLAKE2b-256 eda6b3bb21abad1c11839767cf51e7b3238aa5afe7f18fe577d7f524831cd51b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 04223031103ea24bdccc10d7fbdccba478ab60a5858c02609cafb120bc8a7467
MD5 c9253242bf2a2eed2c700c6db972b201
BLAKE2b-256 2a3ab19a975e7bc968c884384a5659bd05c66e4ced0f43da69d2225a0fee5133

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 1479463e2f77757f35b28b163d46df446a7b9d0aacb5c55ef9b9a610ca954af3
MD5 599f6079534f7444eccf15ff5b47ddf5
BLAKE2b-256 a6cdb8a0972abfebab3dbc92067fce2f38db47096fd68b66279ab35d1dff61c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 f42966f1ec42a2123d501d148d6f9ede8f5d105ba83e2c248b09cb0395b13e6e
MD5 307add946a42597ef4179b606b516f2b
BLAKE2b-256 b3b19b32a59665b671bf4afc2cbf6c5ff551c09923cc5c6403f1239f2b9682c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 afe233c94d1cd45cca20e88621f959fa7ee4afd989b57e2aef680de656ec4824
MD5 36ebbbd778c3c903b6bb79593cdb3d35
BLAKE2b-256 262b1f3f001ff48ab49a9dcf64eefff7781dfb222810973a86d190422a1550c1

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.3-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.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fdb5e83cf9789ea0baa26fc34da82318cc728e1321d4d838a28041971995e0f6
MD5 7d07c5ccc5fcb00b11e1fa18907e4b97
BLAKE2b-256 e9bd88ff2114ce4dfe9d00b1afebe967b09245ccddb6037363fe38ad83c40fc0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 2694aba97e019f35acc7b16c6827de1a43c076d1ed701943ffa5f61ec73797db
MD5 dec53d827cb12f542bc78616cb4d8060
BLAKE2b-256 3b7c1b8694f181e371ea3dcac167b693cd3a21404724c2b985e79ad5d3e794cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 9c87694595ec3c1bf600290ea789275c5065015d5fdd516c13603225d5bb6a00
MD5 c2fc2d3e7d5c894aef92dd51438568ae
BLAKE2b-256 14716d96057b4a7fd598487199362bcb0df639b6e3e864e469238140e4077398

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ef34169c7995192b8d62ad4e1c5016fd047a721e12d4ab4e33c2436ea2639236
MD5 320aa5ec6d23b64628cfb781e770ca16
BLAKE2b-256 a6d2e6b22ff4b338dec23b2381516d3c5c722ee653b2af29fb92c844cbd69fa8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 351f03918407464f5b18b3ffd04db13805add8e4da62cf60c3b242f5469f61d5
MD5 9b733d076dda8e950390495023284b3e
BLAKE2b-256 f1e413e485b6af6d992239c9cc8f24da075bb4521364c62c712f6394c7dfcc93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.3-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2487c2187183e32973249e804c4b687b724591a7af446e9fe6507432c5178a7a
MD5 40dd3b89f031bce262f09528cdb2a121
BLAKE2b-256 557338b6e039e9069b82e6f456f078d19dc02acf4793e304eadc67df004fe916

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