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 and is practically a shortcut for text.split('\n').

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")

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

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.6.0-cp312-cp312-win_amd64.whl (67.5 kB view details)

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

stringzilla-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl (249.2 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl (175.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl (209.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp312-cp312-musllinux_1_2_i686.whl (191.0 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl (185.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (254.5 kB view details)

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

stringzilla-3.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (186.0 kB view details)

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

stringzilla-3.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.6 kB view details)

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

stringzilla-3.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.8 kB view details)

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

stringzilla-3.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (192.3 kB view details)

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

stringzilla-3.6.0-cp312-cp312-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.6.0-cp312-cp312-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.6.0-cp312-cp312-macosx_10_9_universal2.whl (110.9 kB view details)

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

stringzilla-3.6.0-cp311-cp311-win_arm64.whl (61.7 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.6.0-cp311-cp311-win_amd64.whl (67.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.6.0-cp311-cp311-win32.whl (62.4 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl (248.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl (174.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl (209.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp311-cp311-musllinux_1_2_i686.whl (190.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl (185.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (253.3 kB view details)

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

stringzilla-3.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.5 kB view details)

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

stringzilla-3.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.5 kB view details)

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

stringzilla-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.8 kB view details)

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

stringzilla-3.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (191.8 kB view details)

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

stringzilla-3.6.0-cp311-cp311-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

stringzilla-3.6.0-cp311-cp311-macosx_10_9_universal2.whl (110.7 kB view details)

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

stringzilla-3.6.0-cp310-cp310-win_arm64.whl (60.6 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.6.0-cp310-cp310-win_amd64.whl (65.7 kB view details)

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.6.0-cp310-cp310-musllinux_1_2_x86_64.whl (246.8 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.6.0-cp310-cp310-musllinux_1_2_s390x.whl (172.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl (207.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp310-cp310-musllinux_1_2_i686.whl (189.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp310-cp310-musllinux_1_2_aarch64.whl (184.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (251.7 kB view details)

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

stringzilla-3.6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.9 kB view details)

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

stringzilla-3.6.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.6 kB view details)

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

stringzilla-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (187.3 kB view details)

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

stringzilla-3.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (190.2 kB view details)

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

stringzilla-3.6.0-cp310-cp310-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

stringzilla-3.6.0-cp310-cp310-macosx_10_9_universal2.whl (110.7 kB view details)

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

stringzilla-3.6.0-cp39-cp39-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.6.0-cp39-cp39-win_amd64.whl (67.5 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.6.0-cp39-cp39-win32.whl (62.4 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.6.0-cp39-cp39-musllinux_1_2_x86_64.whl (245.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.6.0-cp39-cp39-musllinux_1_2_s390x.whl (172.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp39-cp39-musllinux_1_2_ppc64le.whl (206.5 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp39-cp39-musllinux_1_2_i686.whl (188.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp39-cp39-musllinux_1_2_aarch64.whl (182.9 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (250.4 kB view details)

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

stringzilla-3.6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (182.9 kB view details)

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

stringzilla-3.6.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (210.1 kB view details)

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

stringzilla-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (186.1 kB view details)

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

stringzilla-3.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.9 kB view details)

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

stringzilla-3.6.0-cp39-cp39-macosx_11_0_arm64.whl (70.0 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

stringzilla-3.6.0-cp39-cp39-macosx_10_9_universal2.whl (110.6 kB view details)

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

stringzilla-3.6.0-cp38-cp38-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.6.0-cp38-cp38-win32.whl (62.4 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.6.0-cp38-cp38-musllinux_1_2_x86_64.whl (244.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.6.0-cp38-cp38-musllinux_1_2_s390x.whl (170.8 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp38-cp38-musllinux_1_2_ppc64le.whl (205.6 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp38-cp38-musllinux_1_2_i686.whl (187.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp38-cp38-musllinux_1_2_aarch64.whl (182.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (249.6 kB view details)

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

stringzilla-3.6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (182.1 kB view details)

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

stringzilla-3.6.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (209.2 kB view details)

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

stringzilla-3.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (185.1 kB view details)

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

stringzilla-3.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.0 kB view details)

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

stringzilla-3.6.0-cp38-cp38-macosx_11_0_arm64.whl (70.0 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.6.0-cp38-cp38-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

stringzilla-3.6.0-cp38-cp38-macosx_10_9_universal2.whl (110.6 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.6.0-cp37-cp37m-win32.whl (62.4 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_x86_64.whl (242.4 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_s390x.whl (168.2 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_ppc64le.whl (202.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_i686.whl (184.7 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_aarch64.whl (178.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (247.0 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (179.2 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (206.4 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (182.0 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (185.0 kB view details)

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

stringzilla-3.6.0-cp37-cp37m-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

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

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.6.0-cp36-cp36m-win32.whl (62.4 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_x86_64.whl (242.7 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_s390x.whl (168.5 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_ppc64le.whl (203.2 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_i686.whl (185.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_aarch64.whl (178.9 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (246.9 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (179.4 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (207.0 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (182.0 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (185.4 kB view details)

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

stringzilla-3.6.0-cp36-cp36m-macosx_10_9_x86_64.whl (72.6 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 53fe283c3a92c23edb354aa3d91f01b4f51264d408feec3e254cd1bd2128f16a
MD5 3311ca0595e266d4d09047fbe35539aa
BLAKE2b-256 1826aac151e048220238f51892ef30bc737ded02305ca5473fccff0257ad98a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 5a71e35fa1bea0694f197fbc6dafbbbc082869674a9c022022d0715df9ae7671
MD5 bd893eeeaddeddf91253baaf3240d81f
BLAKE2b-256 5d9d08d500953e283b368c4b56ab825190f3c236a952e8ada1e637b3b633da23

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 cda476e9bcbd400adb2673d979296dfd1f0197bf218c8021698d5410a221f9b1
MD5 df7ad4411bb1d343e9d72b25e4a266a0
BLAKE2b-256 944e2965f1c93598398866357d56e45f910430198e9835ec3100614409e73890

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b5dfa2b322818732d4790d286e245fee3d773e6529c2adb3c3612c580f745f42
MD5 332d1f7fb82d9b5a95af3951fd3a5961
BLAKE2b-256 3a22fd9b7c79a8f657d1e075d255722fbd5006999ab11510d863df61c12cc560

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 70d39d3d39da44ebeb5dc9111f59853dd3ac2a81e60c6fd6482063ee7b2fe488
MD5 5239e669e02f6ce6a613c09b78cbf504
BLAKE2b-256 f6f2f4c1a4c9be974ff7fb0854373e5bd0cdcdf4a4727964959115b9cde6afbf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 94bceaf0f1990e5653894b982e956df2a39a5c778b68def85fe8ae093bc16a97
MD5 99b597644566e8be5158fab0bfd2dbfc
BLAKE2b-256 22d7b8c37f2c195bec2214a09c18448547db777ed8d6777c6637a3ef78280c26

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1ccde31e9e144863c8b5035ade5e8ec5bd5a7701fda95c3e531fa02ba8cffc49
MD5 1f17e9ca7472e3c5a1a2e2429b4a0607
BLAKE2b-256 43690b21b19fb39ed1142fd99bebbaeb91b6a6b899a79f3d19cdab80994499d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 8296cf83ed314ea555b22d4d2e826b3c416129807bb83f73afc47005abc0167e
MD5 c887843a7c40f7d46a6ce8bdf3a44a73
BLAKE2b-256 d23ff4fcb3f5b650caf3e1d8be39b57addfa94eea6604a0fb66049258d48977e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c768b37f4eef9baad6bd7437aaf3ed811210006a2c06b5a4ec286bc78acf7610
MD5 f26b736c442281b38d53a062efa31adb
BLAKE2b-256 392529742156f182b014b40f76604b1ce3e07f1c0af9d840ac3568a76648d8b9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 3e01511e3bdbacbebf6050a06e09fb879c510e5288c3a52d85dbb1676a6f0819
MD5 64e9348c2a12cbb70b451a77fe10adf7
BLAKE2b-256 eb0b01db14664009b219658c9a2cd7b9b44e1f16865900b6b7315cfd287c3035

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 51e1af73177baadbc70b4058f448f7724a50c922926e547ab04e4a8090c16370
MD5 d6482173b7648ecd841cde7e3ea299ae
BLAKE2b-256 ecd5efab49a4eed6bc770aa61ad12fa96d420985f6b0c46b29390db911b45e28

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 26a9422bc0bf28e1070aef9be33fa42c468a4a330c598baa13e3a40b2cd79578
MD5 a8ad9db8e0ff0e47ab9c50dfb416aa1d
BLAKE2b-256 707a8effc4832cc0373bd27476b49d9fda38b13008e4b1cbb7e3e9c949df7a0c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 5a5506d58a766b4a5add232da23811339dfa39dc4fba9523d6b0d8cdb71364b8
MD5 7e3da9af30e4c3459a19f3ba8a4f02fa
BLAKE2b-256 33d2737e19eb85a937438651ea7ed550e9888b2f58015b777b44aa198743bb18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8f9bbe6c421ca96aa0733ce9c0146136506667e4781d52445473f61c2bff743e
MD5 329f56ab88e820408e3b2b46ca1b0bdc
BLAKE2b-256 b0f899b4c8902230d6eb95ab07d39ed5454403be2c435bcdc40e1f859620a5c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2f6c4cf58c1e4e3e7a0ccf93d9417d28ee468f10f6c06905b22b98f94d3b26fb
MD5 05cf29399c3ba45efc66aa7322ed55ac
BLAKE2b-256 7b2c8eecf938785ff6f2290c71a4347bb738454ff3e23ee6b59457f08419fea7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 fefaafefacbc4513ccf5f44ab2b21ff158167c183f5d161fc88e25ee14506281
MD5 8629b6b47219faf30dd7588012f919b6
BLAKE2b-256 4c9e4c2fa3d397cf782dfb6da48fbe3a6e3dc9b36a9c6285590471a0ff54527d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 06c7c49b2972aa46aef18482b013c3067eb127dd575649a81b0f9723e97e297b
MD5 4131cbae939c00539a10334e958d0eb4
BLAKE2b-256 f45cd950d3ee140c25fcb7ebdb77734aacdebdbec79dbe5336dd9d6742f85389

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4987d24fd2c5e0d3ff57fa9a5e60edfa8338db746cf869da7350dee80d65c6a7
MD5 07b98501fb699bc9f1402fb17e6f94bb
BLAKE2b-256 876caba07b2f7b2afe448d69235a9b6c5e4e6df3a494e3b4df7149356131b1ad

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 62.4 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.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 cdd63861da4cbba57bbeb967a35755e40d8a737441bdb95b2f9ad1a97e379ff9
MD5 bdcf42b746de424f40853ea22eac0f7f
BLAKE2b-256 3fef2a004bd7c90dd88e92f92c2a9e64a3d4f4fd6ef342b46fd762730349b803

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f883c1eb24f5679695db3d8385c7983bba12299068777e5770c32bee7ee176f1
MD5 8e2cd6eac8fd514cbb6220c532a727e2
BLAKE2b-256 bcfbc66cec6857e4e1b41e877008a820725d1d30279fd8d0603685cc4cace414

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 64e79b947370e32864db58f4b4b7b616a011480b9c7b782349e7e758d1039086
MD5 a2a17a5cc1242747001c5be22ac65bae
BLAKE2b-256 5b919f712d497ed0a050b804e6f01e3ce5c1041de19b8e71fe9deecea12ea8c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 fcd545f1ba9c9aee98303b5a5c56232020fa3ed85f341e2b30d90c9b6b0ce2bc
MD5 f14da90db3200c3cc5218b01f824ff0c
BLAKE2b-256 fb7d00887d3a11cd518a05e9334ce70bf2bfc5189a2a7f869fcfe5a0f8d38a3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 f592226c37c051b314699b70012688f7e065607ed68c46734343d4bbce00ae15
MD5 e5cb30c7487e31dee66cebedd4850572
BLAKE2b-256 ff1aed0ae3da7d690d30d0fdc42cc79a6b47cf21464cc7e632c7b0f3b96b59fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 004dbf7f7896ea79a1aafea13f724739ed7d07e5570708933df846faa26c1e5e
MD5 636a24bf4805f9b53210892930886cf6
BLAKE2b-256 f7dff134c268229252c1c7552c2802898ddaa5943e9141f19b4913a3a2ac918d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e96153023336e563308faee9fbf0a4b498798636d385ef65f0f7fbe7d52a7e3f
MD5 f5396f1ef218f850c6b9b1b6f39a01e4
BLAKE2b-256 2f4599b7c1190b67be76c4acc66bc8d7f6caebaf34801d7dad6b07b2b6791e5b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 69ccccbac48e012cdb10c3d51da1ef37f13f1a31e745cfe8c324ede08b71cc10
MD5 dc9e804ee68b4e42f0a0d2b62338f9c6
BLAKE2b-256 3f47a027f05aae1b69bfc15ad3bb4f4d15e9fccc28ac2244f41e7f9682f5d5ef

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 9980ecd21471e0056f9b882fd795978a3d4446e2ae392085552773dad1edab45
MD5 ce4d72e7a5427db4432005475b0e1860
BLAKE2b-256 52f0fdf2975dfce7a6b4db405a67dfcc9ab8d4288c4cff029ae68b3975b118d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 18723af95e6193952bf791081ac4b91799c616ecba4f45989600a02417a1315c
MD5 97db802fa54b431a58929720a7e47d9c
BLAKE2b-256 0085ef8b3b6acb83f1b09d6c48f84287eca2700b38399ede225348bd694a9820

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 564eb2915d8d46141c47c1c78014ba64c90be9f27e10633afc845d964ed2c8d6
MD5 50f9a50ad75b13f732df2259ee27f6c3
BLAKE2b-256 4a421c6189b35c2a7c9fbd4e9ed59b2452090b33f2995d3b63d680e059b32da2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 83f872cff17d42ca01d4f2855322cd569c69afaf773442da9fbb0ecab22ac6df
MD5 0cea56457f0fffdfa126952ecc148c73
BLAKE2b-256 2e5778d8f244609d0b8c39c73917a734ad754a8885ae8c025d6d27f37e1b43a8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 174dc9f243399f22bf5e74607a33e89e7a0a8ef5a6f8eb6cef9db85c07c24063
MD5 0b4d52c7eedcaa8800bab892cb9a4e75
BLAKE2b-256 841d2e73430e43b930113ae2a0382d339038db26d9d107c7419fbafe734bed13

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b382f752bc995f50d315695d6fd432ae7b7b6d249e340e497888af568f6a2058
MD5 f7c3117b8df07ca85fde0943b8e76ecf
BLAKE2b-256 209069c93695b0a93bd7d71c3009b06ffdc335883eb8c064ce03c1fb7ffc333f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 219e9fac30f29018d886c67a3891ff61cd9966614613887838ad9af486a09858
MD5 f7438dff59898b6ffb64117789fb6774
BLAKE2b-256 805cd7fb994df741f78742b3e32188f8961855856bf1799d5eaf55ca35c2a4a2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 0b39a5de37aadcc4e2e60b045db3fbdef3a4e78bcc71fd917191e7b88e87eabe
MD5 cc252734f2bc1c5cef3d1fdcccfdfc34
BLAKE2b-256 86c47c98a8f64e25af98df2346ea105920ec281f33d9d5a3d1ee6c5a6c919bab

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 2a59f2b8498f1fe709ab5d2ae73f362c096ae0829727b301a71c1fd1c21e467d
MD5 d106bc71631de670cc5499c58bdb4b30
BLAKE2b-256 cb44dd0a780f515886ee903c2cbfd53882c673b3f108a9565b07f6b753cfcf05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ef8a851664743017e71b8d7221496c97d9cbd53b47e1d4d2e16bbd7413e5f250
MD5 2ec6ae7c430a4f444f6d413fdac2faca
BLAKE2b-256 0a8b9de98d51578605dc7bc4a4a7a76b92709576ca99177a83ffe6c05a929966

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 fd83125c7deec55d9477a9c0a976abe1656c42dad8e48be51f184ca3800baa2a
MD5 26f990270fcaa0b92d6a9e23b668480f
BLAKE2b-256 e8f8be6f6369c8b7484d85418a5a2460d04b59b0bf397c611dd790c37d9d3891

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 fb7568dd3373e07f397dccde36a20d5944ea4120e94788ab8626b1d967c6f0e6
MD5 c25d80fb92eeabb7fb64c28fb9171556
BLAKE2b-256 7307afc01a1cbfb605f2c9aad329a0f82a6d82cd809d9e56a1e4c78e4a681d39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c6ecd329d6eaccb1013c0b24df21da13022092c378f1fc78637687bafdc346b0
MD5 7811682e2c5c0d91d9956d7ee88ed02b
BLAKE2b-256 276c632972c1b890676483b77cc34f4d2e3592e2758e8dab43ab33bfb270d4f5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f7fc081375ac72520cadad1cf8844f68cc0927a52c4817fdc5e89ff7ae26fa91
MD5 72f3c29803a735e818b462c88f506523
BLAKE2b-256 9df764e6ba9f086ad5b6411018c264039580e9d4211c1cf85fe42cbbe79dd285

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 003ecaed0af1468e85fa3b2211c15ff2e0fd0b7ed3afd95b09e52f5513dc1778
MD5 280d9c3cf3837e99df69becc4c80bb96
BLAKE2b-256 86249f243ad2f8d1c51663f3f9a6a5b03ca8dc488590168b9933618e00d9a459

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 32b81459cd477c73b21dc78edc937b33372ae129ec5767013cfc7dc20cab80fc
MD5 154aaed90e23da69a58ccd5da3102a2f
BLAKE2b-256 124810cc77e3f52e048ee705c8466b41aef7dd6d5db20ec7ddeb3a25917d87f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 ece52a2f125c6801ba85289bf3946fe5de23e0172084a4658d07a3c3774ef5f6
MD5 dd3518bf5afb8191ac39e5fc2f62fe62
BLAKE2b-256 26f4e96df7f830f0cb58fef088ea18b9f057d0c73cbc871c8fa49b1684e7ea10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 54a647e5937f76fe7bdb10b1b988fa58d4b1894bba9293c272f9419cc07ae11d
MD5 f0a87c3a24da2ea4962667842b7d4b2d
BLAKE2b-256 a2b3b7185ca9f153111bb1f4d23fd4675679331b60f2cb8c3a750ffa5ff0018f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 a26ea3298b77731154ed7b723a4bcc3f81307ef72ce44c5a68f5219505a2e322
MD5 36334cf90f94574bfe9dcd41fb630b95
BLAKE2b-256 23905cd7fc512bb1466ddf29d046dfbb5a94f5eb4e38b37a34376ef52ad93141

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b279e692a6a39aabfb66808cfb523b9f65c34710da7140aec9b312bfb1253228
MD5 03f42d6bda47b228cc543ef52eab55fe
BLAKE2b-256 6944c5259c595e93d5a4c7649d17932fd041121a09243479bac787d23ef69166

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 023c8f947ac822077e074015771c3a9411dc4effac26f5afe192a8eb81568cd2
MD5 c4640bcb96a1ce94fc4f8bc6dfefc96f
BLAKE2b-256 011f479320e4a89235598dfaac0e107f8551724c883b94037557e10e2b0a8c47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b63f93b9a5e02ff734c5c071fd2834ce9d6ae048bdd5198a678046cf5c58eb3d
MD5 a768ac804897bea53b554613f29a4e08
BLAKE2b-256 4e3fbde2839874f6e916defc292be97bd87cd0c16ae698d91320e7d1ce639376

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 43b89235a396d33aa97cbe26fa1396cfa3a8d5bf668da4a589764c3865def475
MD5 fc9bd97baef3d2e97ea592dafebaa782
BLAKE2b-256 380c33e06429bb136d583639bfbfe357915a68496a467c5ea54183f93de96d81

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 c83a18de81c21922ad17609aaa731825718b004b35fa8f6cc89ca6525161903a
MD5 9b2d72a24e58393c80ebd4dc40dc6195
BLAKE2b-256 d8322ac240056177d84173ee7c767c361fcc8f415927661c3d85ffb392efa655

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.0-cp39-cp39-win32.whl
  • Upload date:
  • Size: 62.4 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.0-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 6f82eb64ef420619517cd45782d25333a9f7cc7af69017199d3484cb862d9d51
MD5 f45686ea23f02d17d31a2613f645c3b6
BLAKE2b-256 d777b1242ba13e17147b7a96e6fcc85ee88e6771b3ffb044c4f7a49d7f23f147

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 dbfe3f69d6b2e1431c21f127f0b23a0e61297621f920c1cbf0144778a110385c
MD5 e3ba262fdb9ed2c3d0beee36291f6abf
BLAKE2b-256 19c262091dcd086743601098e6cb6010d230463bc52b556a8b2e49f462e55cd2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 7395c15c9cceb73f560de2be4e0d6d8db0627447f3fc0f8508882831aaf20d9a
MD5 cd945fab801723cbc682d4be2b1f819d
BLAKE2b-256 535eecfba5507ca99dffefb104a5c39b2bbd71ed3101f229050288000cfaeac6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c8a91fb75e484c567c058cc449d42f8e23ab73c7a8fef9a184c4e3b611e91c56
MD5 360fa77d424429acd48397dc2ebf4ac1
BLAKE2b-256 76344bce7e57b7f9a794fea63f9e794d6fc8c6b1df8fc44ca4f5c62470f2495a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 587e4b877dcda037c636462dae24e8bd51f70b5ab70f0cd3fb19480c9255d015
MD5 26a26527c08a3748280d92357d599abd
BLAKE2b-256 1495b188dff738d8f8ab39f5f3daf1775c20c61262873f27c1aae809abb752a8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c3aa3126d309364fe4d4559e53beef21a94977b24e363efcf9e45477f917147c
MD5 c00868459b4c58a56c722b69dce6bd87
BLAKE2b-256 4bd01ce084e5ed96528723696a50a30bbfd711dea1c47b4a87c48697c6f1db7b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f1b1410b8257c074e64423b6c2234b2f5682e15d2016478f8c0833142ca2ca4
MD5 9e769503a70ba7ab73444e322f227745
BLAKE2b-256 eaa2d6626ebe0547e4916c4e5e4949e9caa70337bd0c12ae43dc0e68c6879899

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 be414add9e55490a0215814cfb3037cb29167dbf91667e520766591a1c6a2fd1
MD5 cbebe469be3031036557de7946a34aaa
BLAKE2b-256 3f3b6d437dceaf305b094aa708e16faac53bce25bb45073c784668e657d06ff9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 345bbba805f0aa63357803f75b4f6c95cf698ef230afc0543ba887218791b154
MD5 75cb6fed730a8b2e53828eebbabc2ef0
BLAKE2b-256 bc3f297263c6827fd543dd677e08b188d8fc62ba67781b02a5cd30dd2131695f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5d108bbddd0d25792c39ed944ccd5ca2fb5eea02dffa097b9806d2f1c9d352f5
MD5 dff4d27541cecbdb8fd80faf853c628f
BLAKE2b-256 b55b013b509375b01607b9718a5398f5950a20f2a465e42e423a5d39076e737f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 72999d8d1157542c5a4ba41f3e3a5d2dbc7f08ff41b0a3e0a0dab56264790986
MD5 ec2424001d802ef75e0935153b6a7c5e
BLAKE2b-256 8a2e8f14e7b0faf2faa9ae5e055b6cd8632bb4628072f2e934105c8de4da034f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9d842ffe984b2095c79c7c68efe3b043bbbe26fa9df77897065a190da3f154ff
MD5 3774601348e6225308271a739f430b6a
BLAKE2b-256 6d463518865013a82c46121820543e1a85f7666664854a9cf9987aa3bbe4511d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 04a320c5223c1b7acd693e61e2ac33b9af4ce019ffe654dba6dd506df4a5df04
MD5 7686a553187381bfe6bacd23075e710a
BLAKE2b-256 4ef178621a221f03ed5b438f4b7ea8263a6acea65d4c455310874f0ce3451815

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b7882677efe7bb6bb5012e04f33f306b86a51612fa24c07e477f97d6db4953c7
MD5 a18649d7b34e79fdff4c7a15b4a7bcc4
BLAKE2b-256 8275183b8bb1f80a61726f3c43205cf908e1495dca557ca94850e1f63f3b3cb5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 dc76ce0ecdd8068d83fe1702827418ae37c70a4749a9fb3c6aec914ea8c786a9
MD5 25afaf5444618785acb63de01fb16952
BLAKE2b-256 fc5ef360ed1dcffdeda98537e95367a1a870edfb6a933e069367bf9bbb74c3cb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.0-cp38-cp38-win32.whl
  • Upload date:
  • Size: 62.4 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.0-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 8c315233be31c04eebd8a280d1e3825d332537b977b7fb9cbf8f69269af49048
MD5 3bee5bcb7c9c292cccb387954073fab6
BLAKE2b-256 b628403a1f999998949093af4c772cfd6243b4804df0202dbda3a81efd0819f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1ffa1af5e226ce15f9edff4fd4209e90a826a86b76e1d662d04a11daa19a2c0b
MD5 15dde6dede3dd7c08504f761a4c97a56
BLAKE2b-256 da538522ce2f262ddffdf244e68c88e3c49a6325ef7a28e8b314ea5aecb2adb9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 cd837f2bf1eda7bcc198dcb00a7a045a0549e169c2cfe51c09cf3942061def0b
MD5 53f41f635eaf2130dcca66969ec1ea73
BLAKE2b-256 6f024a15bff81b7bb4e52f16f2bd3bdb6c84498f46766d40962585cf51640f10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 d991bdbd96d37482d729b03836c31efd51a9f7641d2447d17e6428472dc22ba8
MD5 d0bf13e5c88b5741d8729c14c0f51300
BLAKE2b-256 f56fea357fc577782cb556acc8dfbdeb8db4c416575b0fcef60a1e970cda1b63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 646867cc7fd7b89a533a1712ec27067832d56f39e84af91b790f6846daf3a07a
MD5 de5eb09e329d6d0719f30ac0176d8301
BLAKE2b-256 f87029524dc10fff6844a21ae3763adf371c12a4f663a7be89e2d649c7fb9c37

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 228348419b13aae6513904da1e5cc9cd8207296fabac52e1e429e23b3446bd67
MD5 d8f1886c973f9d69497c30f8501959c1
BLAKE2b-256 2db52650b8c66a5151faa3a8fa3bb2a70ff1ffa76bedfc73e9618306e6c7366d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0b06b75be3d2505bda2c50cf4a8b23206a617de3b747ebc1fca042bbf399dca1
MD5 8215dafd028dc72b385303cab7793f49
BLAKE2b-256 84eb9f4aba625871278613ff5f2ab2a618afc97ba934dba9b61dd3216068db3d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 3cb03d481bf29aeb3f2b981578ad35378f433295aa9d8b36284c2fce761b4e0d
MD5 1bf1f2a26f983eaf8f08319b6714cb9c
BLAKE2b-256 5c5fa813ca035b26ee98cfbdae569053a0989bc48d68521ec404fcd8e088aabc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 4262973af0e0eb20c1bbdaca1190ec4b0baaa62265cea2853f7710cc47aa598b
MD5 4c1025a9f2fd0965d04fe4e837a1309f
BLAKE2b-256 effe3bf2f4116fbaa739f55511cf896f4a11c890fe40467e456df1e5c1ef123e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 92c22b47314d1af747d4a92ef7162595097b723ed535dfba23589dcf6c0f49ae
MD5 a2c1fa5a7770267424767697b37d9b5a
BLAKE2b-256 2be48014160dcfae35c265e854c4913e604a68034b54f56d85dd9538a4e19f27

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f9df62425ce034389fed8b1fc962c2f41728e68272dec16154b2fbab04edf71f
MD5 c873526ca329bc099874961dddc740c9
BLAKE2b-256 f8f0400e2c2d2476771be71c4b45ade04e91fd48f8c873d50480a3501d59e47a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aa3c928a55f406a9d577126838397030fe690a019599d2a68078d97a4e85b76d
MD5 0faf2cad9b7290326d4707d772d00fa2
BLAKE2b-256 ccf92c31716e1e41f663dd312c0f7e385d5283dc67102ca5a9159271c87abd25

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2b4dc6a85744c1d860ef6c9027402ce961cbbb5c76c1ee5f2da531e5a2bbce19
MD5 f7157d08178a2fb5b8b09fe1a1a3a03b
BLAKE2b-256 46c83e68a939c06012091f3dcd94465d9394ec9a13b5a351a07c98361c19d681

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 3f8c9fa111e2ff05fe95208cfa1297f61e3292429a740361ec22efc029f9ebf3
MD5 1b345e2c96e20ecf3bcd43022f3afa91
BLAKE2b-256 ac44f3f784b6a3b4b649e8e63d04b90ef91d1fc2d5097b1f326a22572a1391f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 83caf84fadbf7c6a79eebc97a6e5555ecbfb1e784796a07b936944a5355ac55e
MD5 21609effe56a986f9b2e5467cbf007dd
BLAKE2b-256 628ea0d83de7a94405bdaace5fbb3fab2b80ff477a06ba17702bafaa29110648

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.0-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 62.4 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.0-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 dd4a5466da5b7f1850b305221800a540030b11a3467544ff82cd799b4dac11d5
MD5 95c1343b93c0fee22addde5e531abeeb
BLAKE2b-256 ea3d4cba01b419bbfe387df1c8ea05fbf04543733667c93f415b2668431c16db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c23794587eea5b3997e472c313dafd4728563657957033c9031f9aafc57b485f
MD5 9ef06351e95db5255c8b17e165042fa5
BLAKE2b-256 07000f90bb5b6b11f55512afc1d493757dec4a7b8ba16c59b0e2d0887555fa16

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 168fa6e3fe2102a7b8f70fac5534f27155fc42276a3c703a59e6296f6d24847e
MD5 0f641134d7f79aa8d43c6d73b4f44322
BLAKE2b-256 7ca1fc1e8b54f1717e40758c0aa72526e433ff53b50657ce2e94466544f15727

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 00a7a4528223396f93a6e6067fc31d68aacece1fc06c2e96a3c01ffdbfe39822
MD5 512633a5bccd11ba89e94a681b558781
BLAKE2b-256 d219a66b041dbf1750b1b2913f41421e172f01953f1596403629b2a33fac424e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 aa3e74c04ca82f3f2ab518041efd19e37b2ccb344e8bb5dc2b3d6a1ed176b184
MD5 4b062177efb2e263dcc6711e1241c1b1
BLAKE2b-256 0e6de156b941f595eea155b1d68e90dac0663a4cbb9cec9a3ec1652c4dacf1a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 3896ad5d036489da373d52272261d5f176306234d70d0b99bdea810e316d659b
MD5 1bcf48e25f3ca2ea604261dc1fcc9e0b
BLAKE2b-256 8afc1a3b3e8475e43ba060d1b42755d7731b9fea7c45ce294653d24cc18a34af

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5f0be3b77788217c6504905f10d5a30731d5a94e68899297e59ea62e65824fa6
MD5 3545edf9c59141ae6782e061449c9ea7
BLAKE2b-256 380ff061bb103c468682498ec9b6ae01910035524a7e310cd20263c70909870e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 d95bc1cca44d5c0da99ce5057ac12f3033bab07eef6ab2ffc97b9e44e1687fd3
MD5 413776e0b4cd4134b06339df2f0fecbb
BLAKE2b-256 2a205d5e20ed1adf8243f10f6d6aba71a93972b2d479cced682a77a220e29ede

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fd33c832881953b19f54ed11be031a66b732fe5216abecdca3da751ec81d92e6
MD5 8dc5125481fd901de19c3c4bb07ffa1c
BLAKE2b-256 d0a1132ce935ae416e718717623f65729f7ece5889a6fcf553045647fd3c01b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 467a297e9fc6cd666b71a23542f38c1ac539f85abd89d83248c0a6f544e949d6
MD5 125bb999ab0355372fc5ced521ab6de9
BLAKE2b-256 99ccb896afab8ad8195ef9a16a15b43412ffdc7b3b477caa6f4b82909ce50403

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e8ac6ae983bda842d747d6fb12c5f8ff0e7ba2c3d804ed209e31aa2690255ac1
MD5 18e0587fa84d8953c0d38e518c5a25f8
BLAKE2b-256 2224c8f9dcb377a5f12b611ed3b6046b1f925a0a63ce3b55ae4b0ec28880257a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 59c86fe8dc7a61dc7ade2fedda995475ac02aea4ed6866e146f4f0aeebdef2ee
MD5 7b74d4baa2f6fb1d1a542b776b12f07e
BLAKE2b-256 21724c4772e79a504628bd52a17166babaeda0269334a05fa0fbad3ec8c3ac62

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 d203a9a3fe0e9e7f19bd6f4fef65d054dc0968862addaffb8b03437e39099b9c
MD5 cdc131b2b415d67b5757bbcacdeee20e
BLAKE2b-256 940484dae45ed128c35c32a6cdea53b2bfcdc75a2e249bfffc7b5eb09e4d9780

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.0-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 62.4 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.0-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 08aefdfab652b4218eaaba11e0439723b4bab8a705e6acf3873c6225b31c34a1
MD5 5943d99dcaa018aee3b23f58f0ffecac
BLAKE2b-256 7eda4e122ce26131d49498ed0e94a0effa538dd16f9e8cd15afa2a64d36e519b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f3bcaf464c5842d84c1508a96abbec4cf3cb6c12b7beb091195c3f4b439c56cd
MD5 dedf3db344edd80cb3f4f451ebc28730
BLAKE2b-256 d6ea6797d1d9681434d0c5ac37c09d262f540d66b51e46be2148f3e42081c8e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 d8d79c2c9ee599ab4ad1479bbfa7608f1c246df8a4fb330fefc3bce82e976a14
MD5 9a55d5dbfce483200ca6dc4b5b12e29a
BLAKE2b-256 368e9378b36f824517afd1227e8bec840e646b3414f5fe9328fa2886ccc6cf8d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 d9792eeb36859b5cc612110edcb0132f80f80c29e9558b302a9b0d149e3a249e
MD5 fbbb92cf7640eae553b9f407bf21a2b6
BLAKE2b-256 2a1f7093203d06dfade3dd4b0aeb5b7d2189257313669997f960bcc464f67157

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 08a744763a95a0ef4df13b0c7b09f4bc930fbf2e7fc85cf67bbd44ee0667de16
MD5 2421eef5d280c8aea2a7d5d99af36859
BLAKE2b-256 02d1bfc603adfd5a59710ccef8f0a10f30fc51179931be0df1388cb76a8d6013

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 74af010b9323339f3291846e0e6083cb1e44a89000437cf93572c97b3f6946b1
MD5 1bca128c45c4d9a1853d2df55503be0d
BLAKE2b-256 fbacfc081e54848ab9f95b083c66bbf4c4e154485c14d637c98473a332d42972

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c186ece2f57873bce8bb79ecc67317fb66778bc48ba12c02d558a6553f42ce4d
MD5 9c7f265311952186a262e9b85d878e78
BLAKE2b-256 b26dc717c9ed688a4da53f7fa8dd4023a9123e39cf5d882d9c2b7920359fa527

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 fc7b4eb5815dca41d7738a399a1ef80108adde2903162011dc916c2da4d181c3
MD5 f8a3ad4a24c7e86d34ffde210ccdd36d
BLAKE2b-256 4f2b85b131a05aa13bad63565e219d58bc9c92f368ae9e22f3b4b7030590b97c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 2fb245d33ef458263cc51742a1b58a4aa4b98394915ed9e44c60188afcb3d7e5
MD5 92ae410da8a6f3d337cf91619b485bec
BLAKE2b-256 dde2fbfeefd9f96f63120278c8be4f508d724d3fac0b7cdbe7ad414daf014817

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8a8a50bba29fc44e2d187ebf3995964a1d152ac03a559b6a62ebc77d04a85a6e
MD5 55dca1453bc196cb40bc254a7e088acd
BLAKE2b-256 cf89f029284e18e0b7937c7a12e0cc302afb64f904ac4933eeb660e1cf855954

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7369e516f6e2bbaed19ced1b5d30c9cf20da535163833e6eea75f0b868e0a6d8
MD5 c9164d66dd3dd0e93839eb5383bcfc2e
BLAKE2b-256 84bc3db3d3dc5ec178343a3f80289a3c6be809f395fa9db825f6a1b0181ea61b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.0-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ae2b752b1e1b8a02630e429cb10e6e026579bd373ce89837e615687bbcc56d7c
MD5 2eba5c01f5ed14afa4f1d50d7ef5fef1
BLAKE2b-256 d9b53816e49186515c044e27645315521139978cf2d792bd2c77c0e82a5388d0

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