Skip to main content

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

Project description

StringZilla 🦖

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

StringZilla Cover

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

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

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

Functionality

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

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

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

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

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

Quick Start: Python 🐍

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

Basic Usage

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

from stringzilla import Str, File

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

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

Basic Operations

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

Advanced Operations

import sys

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

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

Character Set Operations

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

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

Collection-Level Operations

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

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

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

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

Iterators and Memory Efficiency

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

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

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

import stringzilla as sz
%load_ext memory_profiler

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

Low-Level Python API

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

import stringzilla as sz

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

Edit Distances

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

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

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

import numpy as np
import stringzilla as sz

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

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

Using the same proteins as for Levenshtein distance benchmarks:

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

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

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

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

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

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

Serialization

Filesystem

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

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

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow import foreign_buffer
from stringzilla import Str

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

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

Quick Start: C/C++ 🛠️

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

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

Or using a pure CMake approach:

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

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

Basic Usage with C 99 and Newer

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

#include <stringzilla/stringzilla.h>

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

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

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

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

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

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

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

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

Basic Usage with C++ 11 and Newer

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

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

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

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

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

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

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

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

Memory Ownership and Small String Optimization

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

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

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

} sz_string_t;

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

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

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

sz_memory_allocator_t allocator;
sz_string_t string;

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

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

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

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

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

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

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

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

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

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

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

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

using str = std::string;

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

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

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

using str = sz::string;

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

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

Beyond the C++ Standard Library - Learning from Python

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Splits and Ranges

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

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

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

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

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

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

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

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

Concatenating Strings without Allocations

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

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

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

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

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

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

Random Generation

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

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

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

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

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

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

Levenshtein Edit Distance and Alignment Scores

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

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

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

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

Sorting in C and C++

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

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

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

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

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

Standard C++ Containers with String Keys

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

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

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

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

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

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

Compilation Settings and Debugging

SZ_DEBUG:

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

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

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

SZ_DYNAMIC_DISPATCH:

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

SZ_USE_MISALIGNED_LOADS:

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

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

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

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

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

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

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

Quick Start: Rust 🦀

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

use stringzilla::sz;

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

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

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

use stringzilla::StringZilla;

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

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

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

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

use stringzilla::sz;

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

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

Quick Start: Swift 🍏

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

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

Algorithms & Design Decisions 📚

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

Exact Substring Search

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

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

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

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

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

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

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

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

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

Other algorithms previously considered and deprecated:

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

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

Levenshtein Edit Distance

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

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

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

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

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

Next design goals:

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

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

Needleman-Wunsch Alignment Score for Bioinformatics

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

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

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

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

Random Generation

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

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

Sorting

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

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

Next design goals:

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

Hashing

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

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

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

Next design goals:

  • Try gear-hash and other rolling approaches.

Why not CRC32?

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

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

Other Modern Alternatives

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

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

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

Unicode, UTF-8, and Wide Characters

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

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

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

Contributing 👾

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

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

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

License 📜

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

Download files

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

Source Distributions

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

Built Distributions

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

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

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

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl (211.2 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

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

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

stringzilla-3.7.0-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.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (214.9 kB view details)

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

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

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

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

Uploaded CPython 3.12 macOS 11.0+ ARM64

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

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.7.0-cp312-cp312-macosx_10_9_universal2.whl (111.0 kB view details)

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

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

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

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

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.7.0-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.0-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.0-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.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (190.4 kB view details)

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

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

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

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

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

Uploaded CPython 3.11 macOS 10.9+ x86-64

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

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.7.0-cp310-cp310-win32.whl (62.4 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.7.0-cp310-cp310-musllinux_1_2_x86_64.whl (248.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.7.0-cp310-cp310-musllinux_1_2_i686.whl (190.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.7.0-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.0-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.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (212.8 kB view details)

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

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

Uploaded CPython 3.10 macOS 11.0+ ARM64

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

Uploaded CPython 3.9 Windows ARM64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

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

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl (207.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.7.0-cp39-cp39-musllinux_1_2_aarch64.whl (183.8 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.7.0-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.0-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.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.3 kB view details)

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

stringzilla-3.7.0-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.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (189.8 kB view details)

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

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

Uploaded CPython 3.9 macOS 11.0+ ARM64

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

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

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

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.7.0-cp38-cp38-musllinux_1_2_s390x.whl (171.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

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

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

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

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

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

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

stringzilla-3.7.0-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.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.9 kB view details)

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

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

Uploaded CPython 3.8 macOS 11.0+ ARM64

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

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

stringzilla-3.7.0-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.0-cp37-cp37m-musllinux_1_2_s390x.whl (170.4 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

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

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

stringzilla-3.7.0-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.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.6 kB view details)

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

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

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

stringzilla-3.7.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (187.1 kB view details)

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

stringzilla-3.7.0-cp37-cp37m-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

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

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_x86_64.whl (243.7 kB view details)

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

stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_s390x.whl (169.6 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_ppc64le.whl (204.4 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_aarch64.whl (180.0 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.7.0-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.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (180.5 kB view details)

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

stringzilla-3.7.0-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.0-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.0-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.0-cp36-cp36m-macosx_10_9_x86_64.whl (72.7 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 9c9ffab89dc43b7669451904c79e985089d862dcee5fba8915354f0b29c2c2c6
MD5 a789a54da515d5082791c5f6e5c9a2e0
BLAKE2b-256 88aac3e204c54b7bd08948f913e4f85c7f9c6d50659b19e97cd1fc1e303b59c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f60f619cce9b5266d575ff9f9b72b27025bebe7ed1b718b37c2c775b7ca14970
MD5 cd12efcb55cb83a96385db82b2523a48
BLAKE2b-256 be28b5242f3e1a92d4704b0e571c572d1ca3cda185613e88392dc804c594c9ae

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 c220a28f875b7b8cb104763bab0d27f728ae7f2d489963a9d67a570dd8e2a29e
MD5 5cf343221b6bd50738b15f6179d82ea7
BLAKE2b-256 b2e09374b1e93a9dd07223f140d8662f01173775e8da054e5a3e2f1f36fdbd63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5958759def5d9f13aff3406f2213c868ad670f9c502564040665a9b8677e2616
MD5 2ee59b43ead57a2dcd98fcd26156bbac
BLAKE2b-256 f1774ab7ba6423748e0ffaafac6b5862d344274651996f9e484c7dba8f719dcd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 33d380d44e4b1638070e40e7457bb11ab6d2eb2e30ce9665d319bd31353b4472
MD5 e37e8469b6d122031504c65c988d2fe4
BLAKE2b-256 e31e6862574f8d82e333968d86e7284f197d5095a38b47443d6f5f0858ef04d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c74b78991e951e9c458b664cbe70e9ad2f445cf70de82b47665495b6583fd0d2
MD5 d3b6ca0e5c34e12aff66e352efc978fe
BLAKE2b-256 9adf007a8a00ab41e15ecd1d4e3f748b1a5fc8767ce816f25270adb5adc78a6a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ab354c63e199de4b689cf901debcbbc6e1034c009a44cba915b5c857afb3890a
MD5 fd6f3a65e016b604c5830f2233d8b7c0
BLAKE2b-256 b1bbeda5ea206585ee5e07231507cc0289020b53fff0746c5cfd66c597c66b02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 42b6fe9d18efc87b84cb2549f42d2764f0c637424747ba8476ea6e187bff9bb5
MD5 de9615ff764d1ec52d397c3d773d0e3e
BLAKE2b-256 18c941c5b19312c55809f58e947109e5b9ff6d122d524fb44baa4019aeacf069

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c63437d45b74b8dabf094bbf30b11b14e9405a813f07cc6f65f62c600784d820
MD5 946aacd84b13f9f8a186020724301f2e
BLAKE2b-256 720d55953f8ac76ed62322852a656a012398aed5618a028ad2d456edf353eb1b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 39ae7e4cd1e0f270a222ee678830099d69c574398e6cebc40144cec87c8892da
MD5 f32f654a8416b7996050d6573344e594
BLAKE2b-256 0633c19a85cee30967e56ed4cf0a2c56af6b89a77c45af063232dea60aabdcd6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 cc08af9e86996adafbadd8ee685bfd4166abbb0ce94eb61f94b0a90243cfc0b5
MD5 08ed8df613b7745f9ecac54699c71bae
BLAKE2b-256 a344cc8833ca2a4976efdae85335de23d36d4031344464371049ff77e038e1a8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c3dc684a3145d2595d4e4434209f59961e312283798a5daf0d012c273e9e1243
MD5 40eb1ef53ce3ac0b23544fcbec3a5ce8
BLAKE2b-256 a1b6aed7c3c08ada6bdbf0e1e31973c077a0be0dc2a31348d0906ab6b6313f93

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9505d274fc50aac2670490a0d84bbaedde0c22022c0a71c56984bdad31530c92
MD5 e3106d115a63f77efc302774a2d4e10e
BLAKE2b-256 d15a93837898ba0b8d1d47c22879d1f380c5e9e9b7e7e5f8c84cac404ca0491d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c596af32ccfc904167da15b2a1a08b3a5e0b6ceafdc1a42ac35e8bd196e68563
MD5 71b525e9b89d95caba1758107eb53ea0
BLAKE2b-256 a22dc8687be49cbf4595c089ce5157784bc5090a3dc11abdc09a8d19a5ff6d5e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 a6a63a59161be130c803df5d4c29bcd306f1894a5ccbdc99f6976a813dd91365
MD5 ba4871189dc5000728fd6c32b894d688
BLAKE2b-256 e2170d4c7d94b07bca5df6a1df310c3f99a5807cf6519e666441c1096dcb3a0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 629aee89df41da449a326bea564493923a48ad61b6477eb2445da97d5f4e7c4c
MD5 b25353d65fc6aefa856e44bfa9cd9608
BLAKE2b-256 fbe67a611b0312599376a25c7e9e5be4210263d810483f858b177bc04e9250c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 acd1522485ae03410e1247a7c142279f2acdf113d0b604e0f470f280f18f6d95
MD5 3fedecf832e312f38b5c9c83049e1aae
BLAKE2b-256 27b59699afb3b502e187d85768bf5991682ab34757d6a6477dd6987eb064393f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 08298d4454e9d726e02ba2d47cc332540153e943d2180ade4ebf965db042cca7
MD5 1f201b6c2cd680417c7339f82fe277a4
BLAKE2b-256 bdc28701bf9ca3037617f0ce2012b53684b3a1c7e21ece79ff9c7cef529fe52e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 862ad89a467ecd157c03dfa4193aa2776121dfb8fdcac494d8f3de9eacbda1b0
MD5 974cdcae12e2d48c9d31c3f7d624ad57
BLAKE2b-256 a5fa1ead57f0835a606ed36efad36c9a4d63f87760ef5e8d907a161223de1578

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e3f4f20ffbe2819abe1f4bf2ce2808dd9b55e3596ae93ea9f055bb97753a6901
MD5 27184cd3b9bf0a390f6e7753a6682407
BLAKE2b-256 5f62faccb167b0749949a05265f3c970210b984cdaa7ad9d630921fd244ef1cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 0b6b75cfecc2128d0fd0f4a43a40dc7ca38f28f3bde166fa6c665c3df3b3beac
MD5 49b8f764739d843332f70b3c333db830
BLAKE2b-256 72b07c7efcd187b1193570ee19c726f2b6e94682a3b2587088f89e708a4f0855

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 065296bd6632e6ab45e6d7a5f0c479ba5a639f6fb6c3088be35e044528f40583
MD5 d79c2c6ba07bc4aac51d519f5602bf27
BLAKE2b-256 d653885bbf693ba8f766d23a54b6f0ab02b66cfbcf916dd60ec25afbb9dbb8ae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 17646578ff683aa61d7e145f8d66f939d1293bc6cbf2fa7f1d4b158acaade581
MD5 96070e9ae4412ea567443f380056e3cf
BLAKE2b-256 957fb3575601a00b00395e2ebd4ddddb390b6a8f4be2a9643e82878c623fc966

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 75e2c4ad5f51ef80054a50491770f209d326e6bbd936a80b8e89ec53a5f081c0
MD5 2ffb191aa1912318105ec1d050b8216a
BLAKE2b-256 a934e6ea5e05dd940cd246bcd3fd431b2188e0e8fd5fa5e920934d0c950896ca

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4a7ead45e3be289e2ecd498d91c52ae2d826b6995c7045cc04ed309355d65d5c
MD5 7d87d9c725ceeba7078c76141a0b4bb7
BLAKE2b-256 4db0bb27b8c6a145a582543e28926e5fbccf9c1540dffb339060b83801fa7f96

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a823d5c5e2ee231eecab53272e5ace9862790acc0a5fdf8ce61ebf1e7de68065
MD5 d90c4a54c6bcc51049ba7267b68b97d1
BLAKE2b-256 5224c5dbfc1395d58726b9dbade3042a6af56137bb879de38c7ee845bc6fdbee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 84055ae8dd6ebeefc8a264f9e112a25e3e2dd0b0b77c3de1a3985ea42567bb07
MD5 6d41491c2d5dc6461f1248e1fa881d66
BLAKE2b-256 823856ca224d2c30ac929374f80fd882a9a2e4d664441d5f820e9941dff25433

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cb1e8a42cea3b616c73ff58ccb924ecb8d660a66e6b5402b0535a574799e20b5
MD5 fa86618a626de51d20675e0f5240f9a3
BLAKE2b-256 94763a8de769c9d150f75f5589abcfcce7aaad0513d722f6251b3e75b2473a98

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 fc4128079e98db12f79a862daaac999dcaa8bb678602175fbad489e36bbc5e36
MD5 2f7af0b0b985309947c1fa4dbb5200e1
BLAKE2b-256 519c6a565437cbe18f89ef0700e3bbb6717fdeebfc19574097f75b501ca18f30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ad6b3e06e50d10aaeb334a20b74147b00fc90c7f629e093bf65aeec38db33cc7
MD5 ee115520b0b976cc091f12592ad9fcb6
BLAKE2b-256 78449fefbae4b521aeb1947476a91d45fdc90d83be6d2f4d540c189234fa6c12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 42a732b7fd0a7b2ddb2352f1f50a9563a0b482d12a1372ffecdcf67f2a272be0
MD5 736b2df1a502acb6c8d4591959f14455
BLAKE2b-256 d611c8ce07db60d3a3823ac0b4a3f46cff5baccd7ec80f67cecb52dbcec30b1b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 0ad33b5688c509c3cd42009f67ca820004acb42cfcd6efaa9a9a8405b88f58cd
MD5 444e43b04297433ff741b860acc6498a
BLAKE2b-256 5eec2f99c225c1ca399f1269f2eb3b1f932ffcd0b1b82fbf5f79f24d0c1e9fca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 ab11329de6838f3b6dadbb90d2b910f456639ba552c05dca2fae6754eeace106
MD5 3e0d4095afc9784c0e0f565865b93a32
BLAKE2b-256 97c2e642e818cd12a8c13374ed8d1615d0c90398ec2888390651d37aa844205c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e7e2572e85a724988fed711eb63e09160a8f35876ef4574b4b6087010dd47448
MD5 16fb226c26e4529168f0fe319703e74f
BLAKE2b-256 04cef0f91b3d43ef99d4b17229a44bc0567812d2f0abbcd20f67f9cb8b4499df

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 37db566640ca922360f705242bd9579fda7f6d6c5df2766f6029939c2699a3f4
MD5 d4405d4a5071652ef020678c08e22ae0
BLAKE2b-256 72f01b93d7492133f4a38dcc9c88e91b98adebd5e25bd027e14d4301a5911fb6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 73401046c9dfb5aae523e422c3a30691ecf7b14a62135b48bb22a9ef14443248
MD5 8a552a3c2a0d51564cf8bfb02555a0c3
BLAKE2b-256 2f43803c32d333c2a55e0ce965f5adf5eb08c08369b4b699cdee038299f79f44

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a3ddebef9511693556129b74ead19bc3d55fa9715d4666d855050dd3b90ef557
MD5 34950b9a84ea5372a6f9cc52ed6550d1
BLAKE2b-256 c1df3843c0e1d0de5c310efa3ddf8aea74fc773a859613f0431af9d97819c769

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 67d66afb189c4a44ecd235cf9856c010b560efa2a752055e4e47521da0677308
MD5 c759dfb7aae98de1f1a5ac1c1cc755f7
BLAKE2b-256 c705fba00f4e02d647e1f838ab99b0844d23cb4b34c6c4be41e5314e3921d19a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 fe86e027e0956c08e3c8a08edb13682dceba9415d91e2dc6d9e0a7d0e16c21f4
MD5 4dc93471fdbe1ac574981ca45f9d7853
BLAKE2b-256 e2f99f315b9bdb9898b434734061e50f4ed65ac8490a71380699576ea6a29de8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 966a141723e0d36dbaa0268fc6d79211bc85649fa2424de928de303190963063
MD5 6eaef0e7941c757bf68a8adc4c66fc99
BLAKE2b-256 4f074c1276b5562e13489d2bafbef2390e68e4461edd40dd43a96e0e29d412e6

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f2955f1346f067cb786088627805fbeba00f7a07702fc2f3040e8e44854574b8
MD5 496b9c26b433502d2f6b852c622148c9
BLAKE2b-256 1daa3ce1b22509e6279c262bdde5589d433f295d42e15a3825deb56a56829b2d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 084f9daa0acfcc260df552e3a805fa49be3681080d5eaad2988c3aad6553c578
MD5 96ea71e1e694abd42dbeb67ccc22c126
BLAKE2b-256 498718e83a3802923a0b97c91a1f4f9cc349b70307c8ea77a628c1456d0e9f08

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 3404fca3863c728eee9eec43355cc986a35c8ad703431d05381f11ccc258c6fa
MD5 70399d12e1ad663b6beaacf6967cdde3
BLAKE2b-256 a82caefe7c766ba9ec6d031f03f0df6f2f52b98053f9479e7278de9c67d94b41

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 80f0e886154b37d4fba226cc0724b463b34c41b5fb7e39b12382495e6616397b
MD5 3014022a344d35d3223c1964a30c2aee
BLAKE2b-256 3088cd6400e568269bca78aefe5e41b3e61f4113aa87f794685ea6b7b1468149

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d905faa4ee67d35a87ac3b82dc4863f560250872287eefa81aee182231c5b01f
MD5 72a00146f1e66f45c37a4d0dd66cb7ab
BLAKE2b-256 55ed12c9983a96e7f7ca8d1d60b5ee1cc78b9c857b66b4333cfd9881a20fc099

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e8b522d2a804e7cbb6095aa31997fa886f4fb434ebcae933aa417656cc260b33
MD5 5aa79f29fcf6eb46ce8f4fa645dbaa92
BLAKE2b-256 6d407bfb15a193c6f57762baffbbecf82f9e3b4935c11189210e187bb2c7dd9d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 91c841fe25d477f28fd62d1b13d2fd210aeb25406a91f13c28f5701c596c54dd
MD5 e3cde6fa83838add58feac9326a42e16
BLAKE2b-256 1a1cea8ee4dc6178a0e6bd6144a04f5ff386c3dae19a6e0bebc97e1b20db53f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 7e96fa1da64d62e22b3d9303b86214d53948982867c31ce9da1380b355eaf44e
MD5 4db2842f90531698c603cba7f2f3b36e
BLAKE2b-256 93626e4a544a25b97a7e589b4274100a935d9efae03424e352342aa488ea1850

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 8a9a04f43c6ce0bede4eddc360e44b14f1393d5cbbc257e972f612760fb38ae0
MD5 16c2fa19add7244c6330be32ba43e5b2
BLAKE2b-256 e1f8798995475e9a6b3a3c4eab857623cd1825b2f8c4f924757a18e5ec4a1795

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 e9cdb907fb4128c1e2e81d205705a702823db197e94f641d26627655f6927394
MD5 cde30607889aedeb1c1842a51b9cd633
BLAKE2b-256 3514f7289b51ab63032f690ae283dea267f48b0eff04586c712e895e5f93743c

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 2f48cc857f314176e425d204dbadb797da4dc66252b10fa59f0ee6a8a67aaade
MD5 36086cc00f8773ca17eb5c1ac0f95330
BLAKE2b-256 fd733860262cd0d110fdfe923322d635767fc969b7c83e2f9ca2c58a8a76c199

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f71b43840612bf38449834bbfd6f0403fe920db0b4fed517f2f109e9cba6cc9c
MD5 117823e4e13be0903b029952af280e4d
BLAKE2b-256 5fdd393630d565eb98a6c2dd465a1809062a32fa191bfec8a4f818e750747583

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 90a7785c3289bf9e2da33b3f8d26aca9c92e7e14f19c439657e5394444ab2990
MD5 5268bb78209ce2e1ae26c1326b544578
BLAKE2b-256 783eab0e686b11e0e029d2fcb2d9f93d266bcddc2e199cc2f2e703c62add2df6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 7a40d581ac5518d7cd9a3c50e6e7339d0298a9c82751a77361c68d8537edf0fa
MD5 688563c61f2a1516e6afcb7d623f0726
BLAKE2b-256 1fb097183a02209df673bccff6bc7850ec5a5ad9066fba88c46ca04dc41fc823

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 39b27edb803f6701fefdf07feb846e1e8e2936c2f9b785055943598a1893cfaa
MD5 45e95d9b7e5e887c4a38ce553b86c8ce
BLAKE2b-256 5760b867afd80d926b61b358694abafbcc1ce6860dd1be80f3d539a765792970

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 cd246e14b4c27f669ba4fce8ed7a35239cfc36eb7033497b0871941e14d083d8
MD5 8c4a60be3068d6a9403cb6095433d14c
BLAKE2b-256 185cf3e138170b2013e64e5e5a8797f92eff2af9884364b3c31a9694a830ddb3

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 47d293dd8cd9216707421922aee8185713dda1199d9f2b36951241d63fbbb2b2
MD5 7fec6e81a2b32da2adab61bf04a63919
BLAKE2b-256 36b13b342255447641f5d7474eee64a5e3f7c85b3ef60394bb712cba7f3479fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 2ccb8d171cc6e58a6167d7349381709a61aeb374cd251288c7246698559c5385
MD5 d04ca60cd74225069ca9b40e4471dc4d
BLAKE2b-256 faedf99ea7e43ded2aaa9c592b84258593d461e06dd5e0355634336304589576

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 01efd520bb6e236797659120f40bfbce37eb6169557ea80e8c5d8661d9d3f8af
MD5 337ae7759f84f57e8bad3558ec00ae6a
BLAKE2b-256 5da5026bb41b55b0957ee73a94476759d9653a5e73b88b2b658c6a4c6d7e65e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3a33a9ddc5d97cda89fa0698b2c2d8b62c95df68efa878573c0a2476dad8ce87
MD5 f22d9912a487b9031d325b0a5d0ee414
BLAKE2b-256 7142cdb6d609071076707a3498a18338699f92085a267d66e79d78a45ceb968b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 11e3ce30d8450403b3cb551cc9d51093735c62f9eb3872af69372a875bb65788
MD5 f0cc431bf527da60773c3b4ce86b45a7
BLAKE2b-256 0d0322fe43f366d680afa5ecdd3c813c2672e051f5cfe44030ed9ae6e95c467f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0cb9eb1220b11c70cc749ec91518bc833c79864d4c8915dfd7ba11779bc6db4c
MD5 017669a8a5ae230e2a8a461123c00b89
BLAKE2b-256 26c4ea1fb668f479a73168bfb72c8f0ae3c92fdb7667cd248856c40f1abe2c1b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 cf517995f031e067c7b4d885b9cc1ef6edac61cb2ebba56b204cce4487a1c54d
MD5 770d15ad62671289a93f55226beaafbb
BLAKE2b-256 560e1327f21c53d6225562da4d8ea63197d1a1c61d8d816a90522046286d5f2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 315cfe8834339d9a2dd5d86a5b8f63b04bf0b090611ab1e95da8046fa85562e0
MD5 1e64424aca5f154ba949e3488ebdbfac
BLAKE2b-256 798a55a11b5c49f508f91c151c39de8b3939fcdb9ed107a2606dfc9769927cc7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 910b97925d8d166043a66349a67890bdf586a34596b40ebda1235274a376b7b0
MD5 43ed00f80784e05557c4e6889c89200c
BLAKE2b-256 41332a6afaa37e07a0892965b78456168b0ff3f325e89e6131fc3424c0e75521

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 2b9f1cb078c7c99b87a50107f69d9b2533111752ca9d459290f4f4dd994da626
MD5 ca364eb6688895be30a2f0dd3e759f62
BLAKE2b-256 a70a5693ccf16e2a9aecde2c8904fff592f4bfc6bbb2d9ac7c082b4e9dd3905d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 13965b2ba8f9b850bae9ed84ace6e6c34859de945c2a0ff0595d35a5052d4bc2
MD5 866f915e3bb5ffeb5022e4983e981ecb
BLAKE2b-256 6de92745424b007d1adcd22fc6f4ad03ee8f0bd555b45f64c63b45140ee37139

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 7f83a1f7c4936a0dc1531d81260c2b1c27729c138f0f2737c7cf3b017f099725
MD5 062a043b1f63f74b3eedf457bcae9ae4
BLAKE2b-256 fe251ea605cdf9e669593852ca507c518b6dba06952b659b9dc5a0111592a655

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 32b0cc92b804d8d2a01a7a2ebbe4d84b6cf092c26eac815af5a112f576e13659
MD5 ba69431a58842be685f76c4b1cc6c6a7
BLAKE2b-256 564e12951ca023c3506d796b783492e788fd4738266cea6f8cb945b7cb93168a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1d794a5f89f8e99850dc185e1f444f7b76238ada785d737c108ae05305f5984e
MD5 6c211b051ec14372e3c3f18c339d125a
BLAKE2b-256 0a603a24875e9d39e444ca9a9d434ca21c5b60f79b0c9eedbf4341110b3172c2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 85ff3d48496ab5969952fc232c9c5ea3b521cb18acc8ba0fc083b32d3ddbefbe
MD5 7c81be79c81bd0ef60af024a0ea522a9
BLAKE2b-256 06290d64845635544060de9db8e9eb0994743d30b19b2d5925dc4fb304b7447d

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 150f36656e1bba30f1c7c53b8346c60eeb63bc1debc9d13ac59d9f9b369a69fc
MD5 41d0ceaa31a6fc08bbac96f81ab71a22
BLAKE2b-256 921d496949b956750466948c8aabfec1f290c62f8e7761d35b73be43ca73d8b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 f19b30ad53924033832d7f0e990b075dbee0555e1e3445f369c8b728b2c48045
MD5 4fdceeb4bd26a7972475efe637a03890
BLAKE2b-256 4553ca0c2dcb8c39a6537082d1db6e139669bafac5293c54dfda097b73f845a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 6a9f2efc8aaa9597a6c589a0f8a21177f3e79be383ac8205526c46baf4d7d35a
MD5 61fd0e8d290ef4dcd1f02ec43a71d484
BLAKE2b-256 09fc46782fb865c3b324571efc42e4b80bd3cd24262184056083c7fc2018512b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1cf88e21a50257b03d69e4b2cd7b385033b96bf6e4864e824b550382915e9854
MD5 6b80e287c59b758041c2029a4fcc480d
BLAKE2b-256 3a14e127f311b32dd7feffd98ea6a3e3e943312d1c9798c127a352b034adc2a2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9b5a85a511922393acd6d7f65b4baef16f8e37af5df4637186c38c1557025e20
MD5 0e2c575166170bdad5d6e009464763e4
BLAKE2b-256 54a04acaf7b86aa6104310bf4ba3f7a0ced30025eb3d67b8b2aad4491408f71f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a089fd60523f0952e69409c26c7e00fc40abb0a3590ba39674548b069e21bc47
MD5 e81ca1b87508290859349b5d0640f44b
BLAKE2b-256 a8c34757b5f8938621017af369ddb021a188e4691f171eb689e501afebfe6c0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 63e13d728fc98d1bf7f564031f42b055585d4d1be0ff1522872d496522696e3d
MD5 e18e7fb52455926ba69404ac4f5b8c84
BLAKE2b-256 42eefb6f8872fc0713b8384e8f84bb5870d9d666922092016ba333ff6efcc5ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 704ad23e625c24e237ca52a5e796ccc60645f847a7d5f876e785bb753c727711
MD5 c2c434ae47d9097b0c187750bf45d37f
BLAKE2b-256 89941aa92f50b40336b3acc0941c88900ffd6d023beb10468a28cef8a2ed8283

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 ce41b215d0baeb94dc77022c0cb940df13e1d013c41c4636f157a21d90b2fc00
MD5 b86995a206262e8c44bb63746da4acf8
BLAKE2b-256 0ba6d065c03ac8f29f3e8aa4efced23cc5a5008912941b3d561df9b90f2b759a

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 35e1b134327805f6fcaaf05f25cc48fedca80a0599f59a56e35c0e06aa9f8662
MD5 83bd6aeefc1b0222beaab27a9d7185e8
BLAKE2b-256 f101f6d74715b2e1d5d4e349afe18ba33e2fa5f66931dd8bd5a003f26d827324

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 386732eedf7a4e00b5872b85c6ec407a4cb311113a754a477384cc0eb60e8c2d
MD5 bce360cabe488b6a2ea76f87b8b34ba9
BLAKE2b-256 c7cc27c1ba4d122c7ab4891a4937993aca28411eb267e82b77adb2e83a4806fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e6b2e7a4242d604881a2b92b51233196b1e0c5c60b729cb73f4a54058d4b9133
MD5 d9456ed894baacd31ece58682b4ce735
BLAKE2b-256 3862586d1b7dcec2f374e8f56f701b8ce5102aae4ee01549b8991c60b98509e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 57b7aede4259f39224fc43be4185f6bc3857fb4309d08b5a1ccee3bcf6aef17a
MD5 0532c9ecd12776e3288b611718296e1b
BLAKE2b-256 b318599d445d83991d9e86aba76ed7544557c36a00e8107b52b248d044b0efd6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ec008724f427bd7f1475ba1679f3905962f3e5a2c3deab67ba2752660b595d94
MD5 552c782c068e6775ec0d12a5fe6d48c4
BLAKE2b-256 64b35d74dfd179c5d671b2171bcf0b5715c2ed7213e2b76a9982152baee4387f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 8dd3f4be3de1d23bfa2ed5a732a6b542b145badb7f9d813187b4ac678a1f1f21
MD5 1f57a9acee724c8589ec8088eaeeef96
BLAKE2b-256 77d64f070e37e83f5b87c9bbfebc4df786b0c4bb2b65d4fe11a19fa866ab415a

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ee2ed77c7833259f29b07c25f58db29d55e8bf80a8ef4ba3ece7486de21023cc
MD5 e31b3d79686d47faa16f6d6cdb9b3676
BLAKE2b-256 ba6ea8b2a9e90bcf049362de1f60d86a7ea7c836e78cd59c5ab830dd6c6a5a2e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 f327e9f325732eb4b70641fa3fece52f4043dbed6588ab823a5773459fc4e8ab
MD5 046acc4ff6f288de98217c124320ea71
BLAKE2b-256 b9596761fe6b30f218620ac8d74e082e3389b30fc7707d756c2a4f87c021719e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1d60cc241bc3157b0201aba05adb742c03f7ae2e802a05407149002bc8f2a0a5
MD5 43b74c37520eb103525d65e4d9d540f4
BLAKE2b-256 9b8d5004b52bf87b9ecf16e97fc22ea79039068c55eded19089c2688eed3bbd4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c32dc3af78dc99aed8590c859453456392ff2938005226e3767db10853243a00
MD5 5843dd95b1d9d714bf63816f0a1baa3d
BLAKE2b-256 e43022c2bd684efe995104098e6c4896e7183fba8e4676de3e53f8239a933aa9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 fb27eaaa7ff52aff6aad7bacfae86387fe242d99d22d5debf7b4a7ee0948163e
MD5 b6fbe464caab4a8696800936a543821c
BLAKE2b-256 6a96954086eefc2e5c341b2fb21235fe7e316d46b5706161fd2bbbe44fd06e05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c9a5dc0f0c613813a7a39ad59d8ec7b26a45f77dbc7675066e52bb5f1408395b
MD5 ddbbd5f28c50a3995773813fb7bfb1a9
BLAKE2b-256 d7b7cc1fcd6cac97f9d8b770dfd5afc286c183345979a0c1396d6c2aa140aa92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 4a94f241f637e5a4a571e019d464e5ef907657d116782e2be8fe5bdeb5daaa32
MD5 a7af6b589d220a45fc58c0db8fad82c6
BLAKE2b-256 f3d4299c27a2bbb0a4d0a7310be69bcdf46bdd2812c226e200a1ff9b82be2c0e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 395e9282f7a7eb5bc88135f22a57d1e009cefc36b7690c6ced46b860d35be788
MD5 9b4f72b75c775c7d2fbc1b06f7def2e1
BLAKE2b-256 0cae019afb4aa6eeaffb4538078da9c7f201ecc9919814390e9d1a041d1ac25e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 457a468d23435c85d6ca69f7ab405d67c3d873ea1f1655bf70daf616d58dce6e
MD5 0af814d34f6ff69a3f2055d8235a9cc7
BLAKE2b-256 0547eccc5c31c837fa144a99d60f1368f21660c10e36238cc8f492d15f208824

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b7e64e1457f00f26c6cf5a87ac8ca87ea8140e1cb4c3226653e891c6b17bb803
MD5 ab87e5624a0e92bbd64b5fcbeaf75ca7
BLAKE2b-256 7b948c67ddc10c99a9d04fd02b820b0a109397e46e60af3003cf1f88a668b5d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 cdf9e250ee6ed6001f70d6cae77765ccc66efd66a0742e736ff25600b554c5d2
MD5 a74c50e33c0976aa21a0b88849c502ab
BLAKE2b-256 d20c89a6d61b46bb7d54e8f8de7842418ff4ae5de66e7df1b20a1a426ac70690

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 2cd63fb8ef1deee30b523fd8b5fbfb6f1f2f66582e11db18e5fbe45ce583577c
MD5 4b0c658f989ba94a715e7fa79e37dced
BLAKE2b-256 528d0113599ad0330d216517eaa7db7ad775e31f17b519ef9d0fb6093f6a66b0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ba540c88a7fc752f344ec4da5b3a7b4b83e2f1563dfdd46ec881368d413f5587
MD5 4c0a4bc463d2aee2e8ad29891266115a
BLAKE2b-256 f5af688bc73d89ccf493eeb4024062a8584896f352d4442603235d06c01d1ec9

See more details on using hashes here.

File details

Details for the file stringzilla-3.7.0-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.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bcef8b4bea3d18eb18195fcf8860f5ed2357370c454e16cac45df13faee58394
MD5 9142722f1ad6b4fdc6507dcf0f418a29
BLAKE2b-256 567ae8b74121c62c283720eea628ef5fe525bdd17e828676c011a3d9502b01a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 7d12831106802711cc325df4df2a43733123861e5d8676cbc441f2d8895b1836
MD5 96f578697fd941508cad91dcb8a48c5e
BLAKE2b-256 76a94feec48f0eaf2f626a1212501dad7d544fcd737ac010d0431d34cca1e844

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 525575f981fc3cb85a73f8c29eef8680dc4055b0183934cd5bc271df00b940b8
MD5 11f3d0b1ccfeaefd22a926de483a3234
BLAKE2b-256 0ac8396ba5bd984b30d7c6d00c083e9605ba10937e96352b1e7be20bec92fa00

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b6cf8dc944ccaf49669d5cac0bd5aaedacda546dfd54db2d2e377d92fecbdf1e
MD5 2ef1de053a1d151d7c88ed883b629802
BLAKE2b-256 ba78bc887a4933e24b8877e07e011f2600368e65e387f698f34cdbc8ffc1d440

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 996971f01095cb776d299eb895868d1e4742b66b96ee08195f6d8ac17b8fcbd2
MD5 22ed62e308a93aca6f0500b2beabfd2c
BLAKE2b-256 8a3a1b330f1a2317a4fc8837fdf23fe77f4d85d24ef18a2e88111f7b957fa9e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.7.0-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c6db5934e729022753b2548740e4acabff28cc728f9ad09dd3419a27a3eae3bd
MD5 96c2f16ef325d7a84cd7faffcce615ac
BLAKE2b-256 c00c7dc34b40cb4ee2998bf01d7ba4dc907e78d846c3d378d392ae971d1886a9

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