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.6.8-cp312-cp312-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

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

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.6.8-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.6.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (187.5 kB view details)

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

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

Uploaded CPython 3.12 macOS 11.0+ ARM64

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

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.6.8-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.6.8-cp311-cp311-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

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

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.6.8-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.6.8-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.6.8-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.6.8-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.6.8-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.6.8-cp311-cp311-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

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

Uploaded CPython 3.11 macOS 10.9+ x86-64

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

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.6.8-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.6.8-cp310-cp310-musllinux_1_2_s390x.whl (174.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

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

Uploaded CPython 3.10 macOS 11.0+ ARM64

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

Uploaded CPython 3.10 macOS 10.9+ x86-64

stringzilla-3.6.8-cp310-cp310-macosx_10_9_universal2.whl (110.8 kB view details)

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

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

Uploaded CPython 3.9 Windows ARM64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

stringzilla-3.6.8-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.6.8-cp39-cp39-musllinux_1_2_s390x.whl (173.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.6.8-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.6.8-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.6.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.4 kB view details)

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

stringzilla-3.6.8-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.6.8-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.6.8-cp39-cp39-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

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

Uploaded CPython 3.9 macOS 10.9+ x86-64

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

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

stringzilla-3.6.8-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.6.8-cp38-cp38-musllinux_1_2_s390x.whl (171.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

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

Uploaded CPython 3.8 macOS 11.0+ ARM64

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

Uploaded CPython 3.8 macOS 10.9+ x86-64

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

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

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

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_ppc64le.whl (204.9 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.6.8-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.6.8-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.6.8-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.6.8-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.6.8-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.6.8-cp37-cp37m-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

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

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.6.8-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.6.8-cp36-cp36m-musllinux_1_2_s390x.whl (169.6 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.6.8-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.6.8-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.6.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.1 kB view details)

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

stringzilla-3.6.8-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.6.8-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.6.8-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.6.8-cp312-cp312-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 899a1e490f9185b139a02a8171290e6e69b00949df02ff21e57ce97dd6e7f9c7
MD5 a0e02b5906d00aa4d3053c136933b428
BLAKE2b-256 a6f191b89d5bb6ada9b9cc19a26e267a5a13c0514a2e56c0e23b6de5dda37496

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 a8aa5de736320d1d627c5cb67fd1008f7052c2dfa4761bb1a10ff77458633335
MD5 bcdb15983dbbbffd58b9f9fbb6b6fe3f
BLAKE2b-256 37f118550a0a026a6fefe2eb97fe467263a43ae0f06791696b163e720b12e3d0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 ccccefed4555f87cc933ba8e71e6ae2a6cc0882d6fb2de83086a927a62245ad5
MD5 bcc0b522bf34763614f68ab146dc7ab7
BLAKE2b-256 70a1246586060df78f543c0b04b9fbffe97c90e3f4cfe2e4d04f1d93efd26cc7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 aafd9ec62f28e0192084dfcffae8689646738f809b4e3fc410e8083e695bacf5
MD5 c7f17051cb421a75f4292e2d63df2549
BLAKE2b-256 7a0ec6f70a296f5272b3e3810d08fa7560b57bbd4b547e5d0f5f0c39314bca31

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 5628186889c4611deaf3f232544d31f255d1b5097f1e38cb2c2c0beab5cdf2db
MD5 248b095e5bc0c58b41816801bf8d46cc
BLAKE2b-256 88ea91f727d47eb6d03374720f1dd917f12dfb864aa2dc34463a37cee9f7900b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 1636d25a2f8bb0b70fc6f8349706e3571f6c0511cc190677f4d3e9f31fefcb45
MD5 5aba03cffe7e506b242f9e3de830ceed
BLAKE2b-256 0ba142f5f59832a571ded53263c9a763b0ec183d71e314b684a8d835d621a462

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 27da880dce4e42fb1414148232f4bf1d86fe426709c9bbacca948b5f29477d0a
MD5 7dbe0b9819b7f55eabc47b01030144ff
BLAKE2b-256 20f891230522bb0645df081b0198e8b118050049c1b8e27f18aecedb9d1e826c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 38c0a87d26d9f1f5888d026022321587473c7093107b8fd3b6648481f065ee7d
MD5 dbbbbd6c1bf44b881a0e052e860368fd
BLAKE2b-256 d07c1db0a097a51ae8fd1a7b14250f523010199d8c71dfcdfa44ab87dc3edb39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ecbf22f7344365c12b35610abf443c3f30f6da875bc7807d27b4e7507a7c0c1a
MD5 0c6821e069a2c8e67b23d3ca2232b28d
BLAKE2b-256 d71c3d5d8e9f164bd081af5b6bc5ff8a659b3068c3e98881b288dd1935a48e09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 f1018b83e4c8a6c10c5e161b9b8f278e738cc6b6618d77ba318173cf0ee486c8
MD5 40c2f7119e3acc745ef3f95801f15004
BLAKE2b-256 6a72b835702a7b6dbcb8cbceb16a12553b836f7a0970c51fdfa61ce058cc72e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 3b183c7ddcb899fc6410ec67dd0d7edb6d62a46a5019b509dda76381e455f6c1
MD5 e8102903e9783a8fae3c26fdb63af133
BLAKE2b-256 5d73fab72faed27cf3b69c4a2f46a93643b98514e8cacd81da2a6a1b8f992591

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b4363ea12a4eb28e8da23047ab7a8b23343fa6b1b11b9f47d27f88f83e07cdfc
MD5 0fdd8f3437a01ea750c579390e5ecd4b
BLAKE2b-256 aac6ae7c0a6a35815a9dc196b89225e9ac896cad74cb701debf04baeaa7f9b9e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 90486ee5acfe3ec79d1c40eb9ebca2daaf0b8c560138f88a2394dc9e71fa2209
MD5 5b37565a921aab60b5ea99c167409d1f
BLAKE2b-256 54c8fc171a12049b40b7bba49ff27dc4fb25c2d03a94f5970dee9d434e45468c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7693e7e1e8f10c202af489c57e4d2fdef65c7373a8003be88946c4955b8c8008
MD5 032873b3615b6532b8ae5c85a011bdb5
BLAKE2b-256 c3abfc3ec022bc082f9a6d2f74598f3eb726f2a18f98e383f4e1f6365613f9e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 fe4f0e11a9aa3e7bbb9972f962196f636eceffcdb86478ad76e2721e24fec8e1
MD5 c4f0d569bcc15d8956286c7849cc7a6e
BLAKE2b-256 8ff032f28641ba95ddcf5d65bea1d56e27b7fd4edf544abaf06b37b98f7c00ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 d31f68df9dec912e3c26d71801abb20a14dae01061b546855a644d247cdf4939
MD5 21c31dd386bfebece136f8729e0b8c38
BLAKE2b-256 688421c22fa387ce4351ab6a6dabc45ace1a6612b7337d5d25cdc07ddaec3229

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 b4ac7b9eb38796c4f62a677cd77d9699d3ef2d8cbf6600186158357ef82d637d
MD5 a57ea481366b175d99d405222e36fa48
BLAKE2b-256 89729a3654f017e06491c196730b1899dd325e79c398def9643884588845239d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 198050dfc2a0f2773fbd72a7502440538b7ccd5c1b83521ef2227e237b2da2ef
MD5 32cbc1d71297dcc180edb1cf8d84be32
BLAKE2b-256 915bc382ec6207f507aa0b0e9c598be6f74e9979e3f1ad66884ab112d252063e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 41152bfe81c204c3689b5938a4f5970579ec01ed3c423643937a335bed6fbdab
MD5 6bc694de7144a772e3a1772f460ba28c
BLAKE2b-256 cd35500c8ca67aa956a7e0e977586e2a015fdcbb8940ca8df704f5fc0e24d31e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 bb2caf5027b4064523e49cc7f19df0a3fdf24871f1441c295c2cc94640668a7d
MD5 051ae4c4a40c3b49d1ad5af75deafb51
BLAKE2b-256 c38821fc381a5dc7e5171c198695e38f801f684adb11860a7d0d9ae65a8451e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 cfab853996c582356bade7d8176982e9820a06b1da3575ed800ef35fc082f765
MD5 dac7fcaaa82167fa25811aa28b063add
BLAKE2b-256 0a03fd1f07213f841845c0abdbb8eec922c871282dd7178dfad09c613428e6a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 b29e49f77efccc1602282a41ecd4f6f7e02efe608add533946e1d596ae33e2d7
MD5 b9652be9e4dd0a5e6ed4acd0c9a7a788
BLAKE2b-256 54eb8467984a69feb19bca1b9857cb70329dcf94f8de87fd73be507e241de0f4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 9ea01a63251eadaa8f4edf63e3a0e73a76864d16c70e3e16fcc7dc007e5f76f2
MD5 c87dd29a47dd2ae40640de3b2858be76
BLAKE2b-256 3e9950d4d4be5a8639b5fb97050a7c89979f4d8ea93dcc842892124896992c8d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 07416caa1043a28e4cbc09c04f152025fc6b17ea274541b706247fdf1bca0384
MD5 5df3d5abe0421c95d746e748ee7ac678
BLAKE2b-256 ed5180287e189019a3c5f02c93e82304437139fde4b5f26141651059e086c1b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 79859cfc45e640962c3aaa3860852d8404037018d0cf135849cb250fbedcd589
MD5 65e551ae30a1b5e1b49057f80df55750
BLAKE2b-256 ad2c310999fc41ec60849ce306036a7fd3d2f8f4c8ee216429b1b2680a4b2d5a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 649e172e973db84f88aa809792af35a36a835b86e3b22d27d9f3dddd210d9d9d
MD5 eba6134c06aad349540c87b06c1b9821
BLAKE2b-256 30b542ab17a933cc30166fba63503ce78d94adbf7f297d16a646bf7c3086d804

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 b5ff9842d7217ed5dd5930c640fcaf4160494f1fb3ff780dfffe4eed4e088a40
MD5 25a7086bc496f9409255b49f07ceb53e
BLAKE2b-256 646ad37dd0f27efcfb9a68f1735936ee90effa820a429003a6ecac634d70b4ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4c81cbb681b12b09e6ef603c81fa83f9bf5ea43dd98186bae2f0b1bb9c12b618
MD5 efb17cf6e7b9f589774402508db69af7
BLAKE2b-256 2e393e8485ee37a465f5fc6ab628aafa5ea1379519546af7f9ea5afd25284473

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4f87414f445e5479a159bfe79cd119f9dedf0e3acda941529b0836d0a678a3e6
MD5 4446fe2bcbc614a7b30b67af5b0c2aab
BLAKE2b-256 ab41aa28d948688016f798bcb3357e45972fab335d856ce29f8691d1deb81208

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 913a8a2db8c9a23dfaa76bcd8abbb8156aff766e95522d246104776aef4d5157
MD5 f00daafff0ada9623ead8006c6f6c352
BLAKE2b-256 f958d0fab3a1513ddba4c93a9fd68b6797cc5ae86ffa45d21c704957acef0a13

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 06f6537e6bacd28c9fa936d844eee8f7ad63327d197cb77ddbd31062f756be1f
MD5 2cd53e05a744d591644ee2d9b132a125
BLAKE2b-256 fc9fab166d5f6ef19e9fe8bf86b6bf8acc59c5a48f3841a04f4cd407a0426f05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 c98d6b05059f223e1183ed52b2fa350461bffa67dc4c237c7cb1ea22d537fba0
MD5 57ed190ab76b8383a98faa1764c704ab
BLAKE2b-256 5ce5771325bbd33e26964fc592178b2e9b790303e1b9995b519d5da2e32aa416

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 55ed010e1774c43f7124dedf44375ddaa91f810fdd431330fec60d57c0432833
MD5 3a1a3c6c0b450dbe256fca10928ab094
BLAKE2b-256 3405a99755759797a372298fc79b8b8b44c35d7d12d0ee63976821cdd3c1f464

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 0ca7d3b6c35bb808862eb844f5db526e94e6e4f75dd6a48bd15c3f8384485913
MD5 dba38bb1bea7679c93593f9552c793a5
BLAKE2b-256 e627e1a07f5de7c77c7e6354196f80781115eaacc7a9e77ad51030e92c4dce9e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 a7ec1e1919c2c55a53a491c8e792bacdc36f2eea82dc46a0b97e5527020fa92b
MD5 d7e974a2169c88c421f9a68b41e9e8ab
BLAKE2b-256 5bba9ce16a23f1eef6fa4df9b6bf3ad7c92caaaecdc3c89bf3620d6104b99dcb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6780cc8f66a8e98f63214b90982a67ee8fe804502e620c412fdeff6ea678db29
MD5 70c258f99daf8124fb5a6e418a692336
BLAKE2b-256 c1cfbddac8ae9eac1feed4b81ab72ad3b8b787d164bcda2dfe06e65d6978cff8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 ffde45d8829c7f0cbc91d0f4e2bffc50952d12e553073226779dfd2fbce18ed2
MD5 29c6289f3179c91a85a70e77d79e92e3
BLAKE2b-256 f9c475c781d747830c62a809b129cb41ba20758f0a6f26b687137d14024b9428

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 361dda3bafc13228e4c068874214aec4dcc3ef68d31c7ea61af027e59a119695
MD5 b45316eba96b6077759211eaaa80439c
BLAKE2b-256 f142189f2561b5916877f2ead29a9ad1a724ac38d50b730ef3b3f8adcd179b82

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 baba04ac3bee92d1133ccda77e50b8d561d0ec45310b66fe5f8d70e3869546af
MD5 ab14131188df0c22571089bdefdd613a
BLAKE2b-256 4c9942fb3fb5ba251665f438eb910c04b3e10bdbc8abf211a0eec0baa5613611

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d49eaa20dc6c5aa01cd88f55c0ff67d467b5bdee117763696fbbf19379bc7409
MD5 199d64bf380cb0c8fc3a1b95d7414564
BLAKE2b-256 1017a095909c1a7fc10e01522f1d6d715def8102315270fcfcff8b0dcc5f4f4a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a544052b6f97bde03c0279a6676d794b032dce65544c780685974a5559a62700
MD5 f69cf269243b7cc41920e24f81311811
BLAKE2b-256 6e54ae6241f1a857fa76352e32ee5fc03cb447534389dab32bf5a0b3e2fd4701

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 192a719a26f3f69a5d41c4c633ec77f7dc486a16935824dd76a8e1cfb3cf68d8
MD5 639bfb4a2af2f35097c9c64b08d381cc
BLAKE2b-256 aa34f48c501610df6aacb9f5a787e0ab5355bf3c13710af0e9b48c95e138e82d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 d167ce1383a03841de9286b61a2e02437a77bcce73d0e04feb5b1a8d598ae186
MD5 3322d562acc34bb547a517bf409adab8
BLAKE2b-256 0e90361653ff80372877415f8ee1afaf756efd41cd8f539dc5c9b4d0272f3f4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ae9196a4262e816c5ff8b5fe3a185794ec2eb578cce24c75b1890ec5bff4ae46
MD5 0ce140f1547a055f7ed7d01e200504c2
BLAKE2b-256 0ad9509dddbe72e458cbe78da3d0b9173ab4bf21b92f0fb8ec111403bc2da747

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f8f828f43635f96e924d53c8b9b634a46f19ca165b31fafefe3dcd7fc898799e
MD5 a8e71b4522fa3b5b73382b23ba00f8ec
BLAKE2b-256 7ab343764098f8f9131b8bfa73e2e3c7370942f226c10b7eb58fbb8218b8bb23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fbf8608233586c275713358d145531e271df48fd480d55ad97e30197199dbf7a
MD5 8211ef26c71b39b14da0efad99ae1e28
BLAKE2b-256 4f17159f91b50bdd2280f0954a1c5c023a56683dc4f25962c7c20b8abb36b8e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 1440c8626761c492e5c2fe5db837855de4f236174c3035e64689b3aeb6761bc0
MD5 ae2b1d6fddab930541ed7557faed9776
BLAKE2b-256 b11ea40f71ba5647fb99e108a4a940f303c1f7325d32d85268c0f528be150d4f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 8cccaa43b68e14abc1fa23793c4be4c7934eb7ab08cd19e031ab550dd66413f1
MD5 2418a4638dc22ffd85ea39843067875b
BLAKE2b-256 6c2f49a4089971051c3562d110a9b98ff2ccfc181316da5ab59b92950de7f9ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 cd323adc19b206e3329d9996c3f4898fe80d36afbb2e631fbdde4ed4d3d51acf
MD5 26f93a88d77bab715e366eb06c93ce9b
BLAKE2b-256 b4f5db7d986250e82f8a2e00664e349305066e07265d68c4a6aa6dc805a206ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 11e60a4856202716edd939171837af6cc067562319d8587ac2ecc8232ec05ceb
MD5 4cd6df834b57a5c5af5cfe28bda78d48
BLAKE2b-256 42db4417785af454961cfe6df7b2ac156a5e312b89b6634b36b5b96137490309

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 e7b7e99c1f897849272d7f05544b9a2cc3940addedfbb207376cdd7b381233b6
MD5 711490eace0720dfa21158e04b05ae42
BLAKE2b-256 cc030977513ff26080fa7647002e3f51b8840a858a32079f861cf5ddf5c85bb0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 652bbfa145c841dfa6a29812510d08eaef11ae828b7ed11d6420b9d4aaf6828f
MD5 fcd36d70cc63deb6ebb199153d45426b
BLAKE2b-256 f7d60957b1bc7fc4d304f22999b848c22d306ec29ed4f30d2202ccd49139b641

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 d2467a7ea86f60951f51492eb83962004b708ee21786cd594514ad471e548dbf
MD5 3026b5d8b9eb1a8b27cd574dbbca4216
BLAKE2b-256 9efe851b781cfdf4cd6aeb6f172f22e79b8992d704c53657e9f4ccc4f1399ff4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 e8ea4f39f560d651118db090a4ef2749ff788ba23a7e693ac2a75779033c36db
MD5 b252455c7bbdaa1ec4208c7e3c676179
BLAKE2b-256 1ddcb4a0094b08b6161d215af1b27987dde923762d0241a89947e7da98d2e1c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 3287a75f6222cea253f94306dadc8be7ba4e9ee75d39eda091c76b7fb1376a1b
MD5 86f2117dc47d5f33fcf4d28ca7a25a24
BLAKE2b-256 ee4d4c14686f794f78eaf571b69a06f0ac418c8c85185291b3f245e3490d843f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 37eab9d4f247673eea0fb209e05609e8495242d0b699205dcc941c45d668eddd
MD5 049fd800008f88667a788bf9e708f44a
BLAKE2b-256 18bceb1d5d76ddddad482b57f6258f368f1adbebf49b34606867fb6e4a9408e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f613aa1ee7d68658efda379fc3a9814a99b7d1715067890060a4855153a9083
MD5 caa197854365f8846bc49c74e6ddcdfd
BLAKE2b-256 5ad0c6dc07cf6f2d2794fbcb12e2f75e771c9214bf008a9ba0635bd97349b63b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 10661f52f089d7021d9df1bbd28a5b2b7e6efdb5a8a9b9385cfec1cd97c7da88
MD5 571050b1b2b03f9b2c1614fdf3cae243
BLAKE2b-256 72fa5157778f9679cc8f49cfbcbe2e37b0084dcdcd6bff8f3f79c153f6d90cd8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 43cefb42843407af658d3fb6c28ae8e29f9b4b5abba2a52429e8572ef42d7634
MD5 e57053da0a6a1472c0e5aef02343000d
BLAKE2b-256 61b0ccbfc0d5c418253b36d9d050d28e5e691f7f12118e73a0fd56b69d4f0ea1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 18c1f0c970e71d1044389b6048d818d237b8ac3c88f7de0534b53e103eda0dbf
MD5 662a05a0cf73adcb752ab006588d6723
BLAKE2b-256 3509b43c562f128a492135f92696568c7f8cd9666f5680170e889799993c571b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6c9dc628464c937b93d1fdb1b19f8edb6ca39b38f43d3d5aa2c2654adbdd1f7e
MD5 0ab07e4f82ff05e7a6d5bcad5c59d630
BLAKE2b-256 baf9e84a10d604ee0a58902642a97d6c0635a397b73e6597e1bd1f2e82cd3989

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b1fc99ab7d8a4d98c5d9adf303cdbff19dc84420aa3ee60c7e4b1f78d0a1e4c7
MD5 2d2706366df7897a66749d6eb350e7d8
BLAKE2b-256 b33f3e1b2d7086e1b33b24dbeaebb3cb7c8d9f849bf7b4fd9dfd233946a37845

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d4333fdd369d362deb0b73e0bbe9d54706ce8d7e4ef5f09fcc793fe0072fa092
MD5 336f99a3c96e986a32890201b1bed8e5
BLAKE2b-256 f7177298f6c9b20fa767d0d6b42e6e7e60637dd4f41c02158310366730ab1599

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 960d76f6d753dce1a1748a3e3485d356dda990c5e96a6a1158246923af56e047
MD5 39ae4235f97e518a31e6bea1d6c120de
BLAKE2b-256 981b9e3f9380c46fcf2c96b68aa2b37b2e80613b650bf59b050c4ce640a94b88

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 85c183441ade297651e3ecbfb327578972b30c22bbe20f34cf551c174d82ae73
MD5 78e1910e3f521f2ebb9293312dd0be59
BLAKE2b-256 7f165b5994736219d3128ebc413060a1040d124628810446de10407ef3baebae

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 31f1d4ccb40d7886c97016b690de74ff73a322c22bcdae1cbeaf3005dcc03207
MD5 f54183c0d967730936a939d68688931b
BLAKE2b-256 24c9d0c5b25bbea367e4fe31aa6091e60ec5ff28783b06ea859d1a3398f50bbf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 140738eaf5ecc4b7ad02306bd78788d95a476dbbdf788d013b6c10963927c54e
MD5 27c003476d6f8d9c7bb60ddde1b3bd5c
BLAKE2b-256 600e2498a0e5146e224f3babf7d56a1a416d188b4d1268017fb7c9cc499f31d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 1b29f1def013802a7e4b243219db9287240f785605d3fab047f475ff7229df77
MD5 9b5574ed94dd6247aed81bd9a0623722
BLAKE2b-256 acc551b7e6601235cd4b3ceff44a7e0b80fa30fc72ad9dc40fda35ce27197c36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c9c8b19e65f89e5659ed259f52af4cffaf6e022153994e8f59f85a8ae9c89e71
MD5 bfed4de86418659d9a13bf5aa1a411b0
BLAKE2b-256 60d88da5ef6f777e79f9983fcd01d5958859ed4a00bddfc2f9ad90f4fb3bdee7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ad2e9b939ad9f6b4cf43abbc784fb06782932a8628072aa9682347f8a9d948d9
MD5 d71c749e7b97fd9910c4166d0b5b4897
BLAKE2b-256 51da1223b4a3437f09b26bdbb333ad6252fbbd2b47d1aa468c996a2c9e911403

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d8e9d14b9fba0fe9475561946d87af3494a836fda60e5bbda6907fd11a7bb10a
MD5 4933a4dd8444072cd71d148a82eeb11a
BLAKE2b-256 0f70a6ed080c7426eda87bc1318615a0fe2ce5af29c04d808c4048ef8018b285

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 703d357080a9cf976c9336a6621dfc1174978902dcea6d819ad532742b7eb86a
MD5 8f16aaaa106e91a9014d3daf675ba18a
BLAKE2b-256 30164afcb8b4b994c2f878f6832b8f6602cae5667fdc60918da65d1bd6a106fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 7064713f1078621a81ba8917b1d0e47cb90770e07cf59ed91bd634800e434299
MD5 d2c76e25119947ca5a2bb111e1226fae
BLAKE2b-256 acca4bb354d194638b577a981dcf8acde8b53dc1dfcb66aabb4b681ac67f9808

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1894957d2ec766aa862c16a716aba99d9181f203db5ad220db628277cbcd6c3f
MD5 8cd782497d586eda6f33d353f9d095ce
BLAKE2b-256 e045cb19d45ee22e4bec9b4c9eb8deb5795bd3cef2b655027317d27db81e3d0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7a51b3215238ba92b0db5e462de7704345b174cf58393bafe969443fefcc526d
MD5 d068265388ff563152e7b3157ac324bd
BLAKE2b-256 39917d681135cd34410319d5c95350fe2372cf5454e73ea7a42539b175278464

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1add0114a5af5d9f1c64c64b711c6e641aaccdcf93b62240c0f0de0cad95cd1d
MD5 cbd1a327f1488577b1189b14ea55d1b5
BLAKE2b-256 9049b4fc83c2e4665f20fb803f3dfeacc6927f6ca51729b129c2a3335ffead36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b1771ed75392b04d7e5903124044f84d4adf7b1c9524a85f353c1e4f8ee9eb19
MD5 75654822a4fa5d0e07382d8529e9de1a
BLAKE2b-256 06f7d08af45b174414e72c0ad817b61ac78b338d553720a1e9990845bfbb18c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5940a3ee60e19b05c2a4789a7c942c18c6a7b48f9aef17b3a0e9ed052d0b87a5
MD5 efee98e3b018280be9ba6ce0e8e117ff
BLAKE2b-256 b341ffddbcef2e9d59d3b344caf3a2a06db2f8f32bf6eedf02b8336529ea3319

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 c0f60554cc0042dd6ae540d1956a7a582d400aca17fe2430012a39cc2616955d
MD5 0199057af43e49d149ec6c20413dc86d
BLAKE2b-256 f241a5e93fde12b3d2d035fbb5578b24f1020c6f7f90b79ce190cb0a6e06362f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 46bc2913e0a19846cfc3d173328c2345048c4a23cc6108d80d8388688997768d
MD5 f5d162072008a42142093c22a06e2d31
BLAKE2b-256 8834afa72306fedc3ade2c37faa040a9d6f4aadb5c5aa1b1002b66d58c99fc56

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 865e0fe1c36f8984bfced02fa2fb6d8a57fc2bf89f06e6b3070706edfaa28b4f
MD5 066a0dc6b49d55de29588398f4317ca5
BLAKE2b-256 ff5ab9540fb84dc556154575c363c83895e40b1279cc62eec193c25ffe2724a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9ba8bf51953651c4dc1834194aaa731621f912d137fa9ff90b510e950b12a398
MD5 06482df01aa8542c6358756d807200e6
BLAKE2b-256 1bf9a30e3fb74efb1d04460889c7c96157963989f1fe676a1c673a0f9968d8f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b26de60f58d8ccf6154af2f70fea3a1bda0b3eb8ce746c4671e10516538ed8f2
MD5 7f65c79c88cab4e23fe1f9a1a9dc8448
BLAKE2b-256 3a4ba5b7110d12c0a5c9445552cff87dbccbb7aa78dccb4165c21f4274c87f0f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 2665bb85fb7c5ddb6403ff6b4be6c93d37473a74f23c66860e43249b83b3eb0e
MD5 10caa174c36dae2afb8f0345c7815664
BLAKE2b-256 3a9db2be5fb3c4c744d11c67f1bf111065c93c7a7c031b8a0247b3104575358e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8855943e3bc6fcc443052eb86991e964f9ae9c7d3e7fdfb0340cd15d42350e52
MD5 3e89aff7e68afb893f5efe70717e4b39
BLAKE2b-256 206cd71473999b6e7fa3ea4bd79728ce5a02cd09bb7481d8a9c9507091acd86b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b937a9652bb938a27dae07d08007ce4262fc15fbfdc8e8e47233f43de4ce1957
MD5 ee1b7f581d437b6f3835f44b202e4c09
BLAKE2b-256 7afe413cbd13394fe5ff7f07ce8bdd50a937ff9e3dee0ca991f5bf9cac472476

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4c4cc0fa3db6351acabd9fd9a5cbd1699243a5db85f8fffa38b765dc93594025
MD5 0cecbf8f37f667ef60da5422eed498a2
BLAKE2b-256 7da995da4f8df2351ef1b4fdd0ad5b7dac6605c3b5f6caedd2440a85f8493828

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 dda759e9520fc565f7b5572900f01a7e6b90af4c404560e7221b19526a0933d2
MD5 0c3a8dcd2165e7d893cda06246d02c1e
BLAKE2b-256 4731168174fd8fb25a166dc3567cbd7518dcc743bf276b5c9746d61287a26819

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 ca20346cb5511646ad16409faa7587513b6f445433d1fcfc2cb7bd23e3db0537
MD5 548eda3323f35c305cf9eebd6e8d612b
BLAKE2b-256 199d32c473eef158ecbb80fc34a100c5613e557f82a9ec45bdb5e4709007a65a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3390b1dcedff6caed7e64964ec81442a75dbd93849b14703353a9282a1048679
MD5 e9760f7b5816812b20271fbdc8ccbe21
BLAKE2b-256 3876c2f550ce77def9c40991f6ffb4ce2da23333272ec4ee0e88108712cf0fc5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0a43f065ff6c53e16adda5ccc864234790c3d8b440bb1e549ecfb4a8fe334487
MD5 3083a7acd61034b2abb9b86813e8d406
BLAKE2b-256 65e5be22e962ecf28167b5a74855456790732ed4840631a0cacd882b25b94d7b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5964112bb68512ef862fc7bf4d5f158812dc170b54561f3c3431fcebde2be382
MD5 76a6f3a67dbc62d755d9a446bb80cedc
BLAKE2b-256 5e5819041688125d946b12aa8d42c8f1f6c25e6d8625a47e3c66f467b4ecd81f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 17ab720d21a3848ce998ba6c2b988e6043954901fc4526191fe9d00ebf0e3590
MD5 9ea44fd543143c3a82a5c8606753093d
BLAKE2b-256 9132dc594f0a131fce2a2513a6678e33d988b0a66343ae810ef23e4544889a23

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.8-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.6.8-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 8cee1e874e35c9325912bfec609c1c6794e470f98509afeb31c7e5859e66daa9
MD5 9b0dd57d713670e885e65c04e2fe0eeb
BLAKE2b-256 2bac9865a789cecbe13d341fb36453145b1d873a77cca0b81f3fe34ab16b080b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 3b579790fbdcb52b3e06f1a420d1a5a13efc68e8104d6a93d6b3fa07f7f0a7c6
MD5 e1c2e0e980bf03324d5861a554cede0b
BLAKE2b-256 bab8939a4ca469231d49de6eb49a3027e92aff38a923be2c0d2d6c34fa2bfcb1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 cc843f76d1a81bc7527fc616269d57863ead0942231546c26fb3fbdbcb2b2b2b
MD5 968e820c1252c985513dcff0ee195908
BLAKE2b-256 9aa7f5aeceaf90625081e4bccb67c498c51618d500c2c711190c9d12e54ed7a4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 857c4bfe4cb394ed8018c281352c320cb3a5e2a17437eec0797bb544261f2d6c
MD5 9a5fe0b0e7ba9828d9497ce4fe178f8a
BLAKE2b-256 127419299961080fedf3234bdd1149c3eb4001d7972b6a083380cbc7cdf30d91

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1d90e968b828e1b543f9e5048e2a0521efc59b73bc3e784c3e59d4778f3e3225
MD5 98a9c618a07f4bcd7920bc45d123665d
BLAKE2b-256 ed9aea28ebee74ed28077da8d78354016d79be690a19159c0bce7c7f762c2068

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1909b1fe761d662d76925481f37ddc8078e677550114ad3c44a568555affe300
MD5 1b1d7b036c8ce481055fe5053b780fee
BLAKE2b-256 46744555eca5d99b26cffac14e45f5aa59e417256a0cb3c0088b7953a5923f62

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4ede9f762b932ccd67d6b93deef6b63f703df0cad694bf4d7d5390b27ec8b764
MD5 c3c20bee13cb683cb430f5b163c0b017
BLAKE2b-256 896010c63123320cf40baf147eff001b83e6166eb35907035f7c9c070b63743a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 593787d02b9b359aca421cf57028f2d437b4f187d433fb789be072edbdc9d0d6
MD5 91b8f97ab1170adab8e909807b19762c
BLAKE2b-256 03cb173f38074b0bb772f3b4a248d44daf75e4652ea504f6f19aae2e8495177f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 da26b2b7bd246bbc31becd42a4a706bba4336f956c25bc10d4840811481a74a1
MD5 c4ca7d9203e56881e274393dc851fab7
BLAKE2b-256 cc17d21ca1a850742219a69fa8d00867c3710fb8296fe20deaa525dc9b5af1b9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 309437af93ca54838951d53f66ab05f448179ccfbfc80e2a4ba790431220aee6
MD5 be264db5a048d03ae2e17d51541c6386
BLAKE2b-256 05509b14b3d2cac7f9affbfd30b5e3417be77a84fb28be7508491c84d0bba9d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 24ca25494fe206173ae2b5f772cf3bdeecc28c09880e44be0100a04d0df152f0
MD5 5ed717a5f973b25778ddbcf46c1cbdd5
BLAKE2b-256 f5d0df68abf36ab4e0cfc647e514881896e06731a3b4d0b4797bb44f92790450

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.8-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c2408a1026bc6321928a9be37215db98fbb38d1b4469d47ed56b1d9cb17ca9d6
MD5 c92fe4446eb85339eb9079413c337d72
BLAKE2b-256 a76b74dad2f18d7b89f024fe07610b018c98130036b8c0ccf3dd3ef789bbda86

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