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

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

stringzilla-3.6.2-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.2-cp312-cp312-musllinux_1_2_s390x.whl (175.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-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.2-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.2-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.2-cp312-cp312-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.6.2-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.2-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.2-cp311-cp311-win_arm64.whl (61.7 kB view details)

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

stringzilla-3.6.2-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.2-cp311-cp311-musllinux_1_2_s390x.whl (174.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.6 kB view details)

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

stringzilla-3.6.2-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.2-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.2-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.2-cp311-cp311-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.6.2-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.2-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.2-cp310-cp310-win_arm64.whl (60.6 kB view details)

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.6.2-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.2-cp310-cp310-musllinux_1_2_s390x.whl (172.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-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.2-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.2-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.2-cp310-cp310-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.6.2-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.2-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.2-cp39-cp39-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.9 Windows ARM64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

stringzilla-3.6.2-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.2-cp39-cp39-musllinux_1_2_s390x.whl (172.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (210.2 kB view details)

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

stringzilla-3.6.2-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.2-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.2-cp39-cp39-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.6.2-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.2-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.2-cp38-cp38-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

stringzilla-3.6.2-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.2-cp38-cp38-musllinux_1_2_s390x.whl (170.8 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-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.2-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.2-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.2-cp38-cp38-macosx_11_0_arm64.whl (70.0 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.6.2-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.2-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.2-cp37-cp37m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_x86_64.whl (242.5 kB view details)

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

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

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-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.2-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.2-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.2-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.2-cp36-cp36m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.6.2-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.2-cp36-cp36m-musllinux_1_2_s390x.whl (168.5 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.6.2-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.2-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.2-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.2-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.2-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.2-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.2-cp312-cp312-win_arm64.whl.

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 3ec99f1df02bc1048e5fb1ee4ea801fbaa159c71a60e6c64192a06b21a40bb75
MD5 b08f1c9e2a2b3a590bb66344181707e4
BLAKE2b-256 7e08ba372738df98cf003db40ec809897344b46046f1330f2d50955654f62193

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 165c5ca49a94b00f13c4d90884eb552ebbf3c902a94fe0c88e529293d202c71f
MD5 42b53deb789ec9924cfe9f7211c66d8d
BLAKE2b-256 ed84ac80db59707eb4ce3d384cee004a5b311e08b529a73802ba7238df2e8cf1

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 664437838d4bae335e82d9b00478464a7ebad5df1e584e355c560dd6afcc9985
MD5 b2393d9bcca0c3eabdc33861e3a4691a
BLAKE2b-256 cc050e56d29c36110091139a38c5ce971e77af84342d111ae7377d19223bfce9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 73de7d35a57a98c8ea4e1fae0613d108edc431b9b44121c6aa577bf10a3c3ba6
MD5 eb518d30742196d200bff0d4515604be
BLAKE2b-256 07650ff9765acd791fc42e020b41a1b989fa4888e4be4c2de789e121ae4de90d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 0b0a87ef252de61b544c0f3be27503eec38c12f936aac6f781fe82cafd93bbdf
MD5 393d989b84fa569ac50cb33f1b6312bf
BLAKE2b-256 11ac8cdacd730f36151438e0cf62fff47211287ce6c154698a9200fc74d78182

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 e71d59e0e52567eb0b9bf9edf29d3ba14c44dd9e20141e479655423291abcb4d
MD5 558ec6e2dec1950d4f49113cfdce2e30
BLAKE2b-256 8210284c64bd8ba651f1c2cf5ae6f88ad83607d3feeb719be103d52ebe23d1d3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 6c0a2f62e98b8ac99a5802df5507a0066a1ef9700f79185932273a9a1c0f9ba9
MD5 13742793b24759131ca960669a289575
BLAKE2b-256 cba3a169e30841619e65bf068df52a8f2684b744aab1aa61debc877443a4de85

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c346877800257bc8dd4a920712ecbc3bccfa46dc5798582ce9eafae2e0225840
MD5 0d0f1026f4de4a67be3edff6ab305237
BLAKE2b-256 efa156ddc477b1c6a97601b4d56960f84a6cf958ec3b1ad54de7e90ac0da6f01

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bf2752156e46892c83aa42e222ce37b63c4d99a56d817f6f54231480970c06c5
MD5 8b255efde7d70a0525cfd60014ff49af
BLAKE2b-256 26509206766a65e5c62430acd65dd2cb6bc2db1ed52f8848618160ea26c2ac55

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 661867e5ce08cff3add8b47108b67a6cf05ca20f4603816e1c3da45fbc3844a2
MD5 ff9bf36726877c00189d86fb2c922d87
BLAKE2b-256 30ca0395d732c59bb2589b9d197001d3a1ab9ccd4c947ab1915a512775398ab3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 8f19e348ec1291699c03bd093c7813f748bd958fcd76651fbc7012a2dc755c61
MD5 fb1bae8ce5cb995d98cdd0a4dd7fa598
BLAKE2b-256 dfcfdc7026ccf82d966f6d635407e7bdfb9c25194d4f7543bd24b6af97e8f56f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8284c3561ad28f849873e223ce140473788bc03c542055dd847b1137a4d45dac
MD5 9bb6d95bb1d0372a6bf1e2904232e9f7
BLAKE2b-256 144cd2d2653561cbbe02c17ad2b2208d5707ee21bc52ae3b5cd0cf2c8ab87de3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9e8de8b8caf6663bbd154c2ef952704dd0042471361aaf26bc10368d909cf5f7
MD5 ed73f9370d09ffd3e163f4fa410177e9
BLAKE2b-256 8eab0c08e7a7cad0bc626483318350a36c813bca377865bff607cf13ad26342e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 13103923940187ad6a0875e34017b9ad7898270bfe12b5df1459452dc60d2ad2
MD5 3eeb1930d9f73ea54f77c1c96197c6b3
BLAKE2b-256 28ac3eb3050af52a1f5ad5ad6f064f494694a0bf2c9aa7878b40addb17d95e48

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 e5644ac94ffcfdd77b2d3389e005a8f88fd8b3ec46807abc2f109f91a2886bad
MD5 d9aa9c12d12cdba9f6f9277535e15fba
BLAKE2b-256 9bdd1c9917d9577d149440177df850b5c3d809be91bd8e0ae6ddf9685ea918d8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 32b44ede13e049fc6ff0120bd00f4367fc3d3b1745f03701513df98c29c44c2c
MD5 441aafb6575f2631db467f57b979dfb0
BLAKE2b-256 0b7074ea1751b56810cad5e570b58f497117aee355e5965e8fa5273bea91e643

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 8bbcb680e5a5c32622d56cd9f84ebe9c9204ad292f9566006238353e9a3f315d
MD5 c216ba7ba2c21013ca1c45cddbe491b3
BLAKE2b-256 c892b6f73c36c66ae7b4ccd6e3e164466a00b386bf99df36ad073af85bd7e8b7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 20904aa68391c32d64fd3f4af1b418a85acaa52a0721121908fa433e930b73c1
MD5 f44a7f19db971e593d3258d08b25df2c
BLAKE2b-256 253b859732c08d2c79e3cdcba3b080b6877d0afc2f1f1f6339d5ab567bb354a2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 1ba20cafa4a2d5f00155be60538b4ed61f1627e9788a7a28fbf55a4360ecc41e
MD5 da6a462bec125a2f423c231470657ab0
BLAKE2b-256 17115cb3ef5408ba71ce752ab80ffcaa6cddf20515cd5f30b5fb82adb6a5d4ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 89bb22e7563077ece662770ca9dafbc1ea0f11473ac5c3df4a6fd379e972ea48
MD5 6c48c76b6d11400db5cc4742fe4efd24
BLAKE2b-256 91fac29a788e0b7c1fa4f74904d449d51734dff27cf327efa50b32564f1de2a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 f8eaccb5a9a79f0df2d98f0f537890b2cbfd6830589c8911ef273ab96585eada
MD5 4f5e98601bccb500b914060613793946
BLAKE2b-256 61b2121cece76be16625326971c90b0487fc4eb2dd5cdca6f48be49d27525862

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 3dfb70f3ba4f81cfb408fcdd790d122c9483ef4ce9d4b32d33ea18526333a635
MD5 cdf092351bcb67a180dcb5f92599491d
BLAKE2b-256 ff02905033fe7b77c841c1d35532dbb77a841acd5f3e949a586a4ddfeaf26933

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 5ed697aedead353025eea2bda55ced2b6026b7a1b7febdc338ef9cc7370b8bb0
MD5 8fbd39ed19f01601db03df73f5395628
BLAKE2b-256 e685e1ee352c8a3c90d56c0b535569649cf5cbafc1daab31d6eceb891c40021b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 915ce666599c94491ce6f5ab375de38c79699bb90087edbf2dbdb4c41c7fd15b
MD5 6aa694a63410fc6e562158871dcac98f
BLAKE2b-256 9c485aeddc8e5adcc0b6958a49cbf30dca3637224b149f7655bcb8490585c524

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d3b1d37df14520323f3e9e5927003b6664d992d3c06704175d6c83764fe7dafe
MD5 b24f9ea51036ec6233a6bba6c98128e6
BLAKE2b-256 b81d5ff8f2b6fba6090d0fa46b575ac01a8e601b4b2a04f31b310c6c9ab76596

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a385e90108cb22ffa4d59485ff89fb43d32187e9872c6d37eef47f8bd702cf32
MD5 237b8d8618e6d198983cb919fb233b04
BLAKE2b-256 be1aa55e4665c05bceb72776aba1f8ea591ec1f7b2a6410462d31d7f31f64053

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 ce40ec9d772c0e3c14236c68cff0ad78547a12dcf9982e26b5188bf9d467c1b9
MD5 40295886b3ed8dc00663579f5e897124
BLAKE2b-256 712838111d27f6806a8cc5f2f815d557d44b5f557f25221c466001406f01bd26

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bb98c0621e3221c19034bd75e4a1a49663c9f9cfa3bea100e7b3ee1f5078d59d
MD5 e2c34ca0a8ea0badf6489f3b940888d1
BLAKE2b-256 474643c054fef44d5fcf1439cb0c22a853ba3cc9ce13dfe9a2ad9d79f009d5b9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1bbe9d646cefb8c7a9aad7a7cab3f1073a86abe66b69d3a83cacbb12ec239bb2
MD5 35fcfe7cde8a019902c47d45c5b71ffa
BLAKE2b-256 89c1bbf724bb356324876da3212410441204f8e65744116b3b66232e72df2e6b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 71fe9c1f98f115f5bf235a115cf80f9f52f5bc50d743ba5f1a133667cf1eaba6
MD5 942f412113a7318b53207673366a2eb4
BLAKE2b-256 995fca15fbd6fa0e5ad9e86ca4f29a7e70ed6a30f8b6cab3c20fcdaeb198428c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 bf422a7114308cd0fe201c2481c32ddb6bb842f59025f913cd93191dd2b0bb72
MD5 92025815406e25d3de44c73f1e505552
BLAKE2b-256 f6f1733db56a46e34a67cab9f08fab618d65ecbd2223800a51ea2a52a2065f67

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 6c1ea890863f8dbdaf46d20f7dd27a9dd47f897d15cdbefbc1403edcb58d3898
MD5 7e48f7b270d16b95c3fdaa3166748fd2
BLAKE2b-256 d5736ab3b1cf906f435f9619e8a66b7a6d99e1fcb8c137ed5ced78fa030f6942

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 b72c2471dd319d5a90cf61b588a5c0f375040aee56fc391079a5f82ee9bb9a01
MD5 609573556cd08856031a76256899aace
BLAKE2b-256 1607c4cefb9ed506989f1e6a1dd80eb0bdc0595648ca0f1951d16d3bc0fbb14a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 55e3fc98241ee5a41aa69c6b59a9d03fbbd0aecec8504ab81d6eb80d4cb705f1
MD5 1442bf76b640f6171f7486782232df9b
BLAKE2b-256 ddbd3b9a762620b3ba3d9f06b4060483be099a333d67c3bfaf05d454530c3967

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 40dc3d2b2d93f812b2f5185d2ff208d85cb8ced483642dd35761411156fc7722
MD5 1b9f22a642785d49d3ab765489fcb89d
BLAKE2b-256 7ac781f20dd9b2fed771c17656e5189ce7bceb9154b4316de2855272ba2227eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a62050c1053e23cc7e5aa183963f4ebde53ee9500942ee1126ed87d1963eb46a
MD5 2b191ba9c8a7f2fd86dfb72718b04f88
BLAKE2b-256 79256341f58315c17be97171c9e1eb00f4c25a2fe5b5ce085f342633cff0678e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 05582bc6596ad945d69f98ae90ef26e04b05425e2eaf95982d5a9ff7ae5762f6
MD5 adfa1727a1f23d85b9661272a101f21f
BLAKE2b-256 75e1245e1135d3198b0117ac17f0e8267b75845dbfccab16b1caf855b10a253b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 15147a9ccfa9e26f1a9c7dd7e66d523fcf9c6c01b58968c45688795c8c69ba34
MD5 77935ee085dcd49e9769c08d2106da80
BLAKE2b-256 a1fd28aa905e1e3606dd948e3f13ba40858db95eaf53cce647099a77d3deaeb2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 54a8d02e2a34faa31acbcf20a1de8fc5f2bb4eac476a4d7a0165c2715e8ce1c8
MD5 1ef1d4b8219302f1e80368a7614db075
BLAKE2b-256 de0a380b614c2a4e7b9574c0aa41fe7130bc4373f92666d817ae4ac63441f606

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 9c9dcdc6eb169c3357091e65e40f788e72e59a85a61ce3c6b927a61276510e33
MD5 e3028d5ac5635d088c446e8cfc917b5d
BLAKE2b-256 e4b1786d56f23c74be77db2cef0cb5776e1cffd6a42ebdde4dc42d39589d1558

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7cb351a8f92a129747be12a18b88bc2c42e72c48a295edbaf9c04dfd66e06e75
MD5 ce46ec08071d96c1bf8bb9a48ccae3d0
BLAKE2b-256 70e18d69d5ea7baade4088f8848b0a0fb6f9b9e348eb646f814c4ef0071ae70b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 fd95cc7ceca43681ed8af62f2db3e30d86b1a6acda5f405b4e1351fd0b8e25d5
MD5 57099138bf14117983f0cbf49f2927b3
BLAKE2b-256 c2a26de6a822211baba7c6f74723968619d9149133a929c9b16bc6af567a454a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 3bbe9e6d1496014c030fcde6b1f356f49bf4a27e94d75c77ffb7b152bcdd5959
MD5 5963496a6ebfb86ccf1935bd905df3b9
BLAKE2b-256 926a6117b9b2bd8ffbe4401e076c52a007ed12e05c24f32e4904a0980627dbfa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c4ea644a0cd6cb63dba2a3e213f4b4531a4b058d4f08f41adf735019f18ed085
MD5 e5a1c0bcf78ec13a19a7a49b4f1234ec
BLAKE2b-256 ebb186ed4af311c143cb10246a5a39e77978f80c3afbfe4a13b62a410852b4e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d70a144a36e911a22c86140b6fe358eb7262c50404cf643bc14406d19cef90ef
MD5 5693946e09a7a713f9beae609a870114
BLAKE2b-256 07e246dbdd50fc7d75140cf8686314fd26d985643a9aafbd004163634ad6ab0d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 44da242d548b2af048015e0af92280b2afc05013051778c49b0d0ace086acc02
MD5 973cc30db9e5b49b6d0f64e58080b3b6
BLAKE2b-256 1490e68c7a622aa11371aafca165824c861c459df6cfc36cbe876e9730604a52

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2ff36e339cb2e58b1ce9ca1c4c8da9903bdce51ea05b9f9a7dc42bb6432967b0
MD5 64da50bbafe5b5d49b7f85b418e68ca7
BLAKE2b-256 9b74462e005c7aad9c8e47f0ae622e3d32a2fdeed64b96ce13243581656e6a07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 38d5116a70e5584e2c91daa041981c555bf4f39a3c5201d2e49e7b859e8dd1e8
MD5 e1faf06616738b38cbfb630e9bec5a8e
BLAKE2b-256 c44f60f02312bb58e687135ec9233db03871b12261301c77e27ee1a8180293d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 7f276c6c9395220c36be055beab2fa30884ee4d94e77b9c44f16a67e393201de
MD5 7b1c02b491db68d154dc98f1c7d2de7b
BLAKE2b-256 19f707c0819351508d290fdade7bf6403f589faac86709360f1d0b24a609306f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a7f8dd077dcf110679a167edac90128ef0d31a4fe6bf547db796705b6341db15
MD5 6b69ac5d8a1dab8853d0cc85a8b97944
BLAKE2b-256 6cc582655e23a3efd4840b98b840c4c67c48b4d4151114b2f3b575131377277f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 296da96e57e3f19a67c96ff6ae2f542bdfd63470dc735a7215fe91a739686d13
MD5 b01ea425f68a0169e96aefcbedad01e2
BLAKE2b-256 30768b0f39e917021ec7df37a179bf30c7a268445e113d7c3b3b9a105bb60c2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 76e574879f81113a8ce57223e7bc400f85bd9e9bf8cfda667d87681d694d5912
MD5 74b8e5d70bb5e55694b92314b4d72f0d
BLAKE2b-256 8cbac906f4b473a3201e4bdda5810ce1a398213ba4689a232b09dbdb6df29d6a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b5c2306fcf7d3d36302ff7b951c0d42a0dd834a6d5103d5466010f60b090c0d6
MD5 cbcca3980e87d0ec6f09dc290b62170e
BLAKE2b-256 23f3dfa538ff55a6394c748ada47f37bffd3703a5f6455c5a6845e00c1831720

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 2032cf693d1c619364a52ad3d171889cab5360a839af4be6fe9b08b9edf519f7
MD5 cafb346cc53eafbec19d3b37cc20406c
BLAKE2b-256 1ea98e9f8bd4879ab8ea0f5b6ce108a968ed77a264c31dce84e5d817d71d96c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 d2db81862a71583da26444abcf4e6dd03878c2cdcad1bd8c417962e42ce84504
MD5 d329073e9cd55be6a103d6ed0e2a02fc
BLAKE2b-256 20adcfe7b193293bfbe81cb1765c67219326b7f090ead5116b9e01acc3675dc8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0c2e70d1371a1b2f09b2a57b2306643560d5fead755a8d87143c7818e2749e2f
MD5 b470caa4df5cce1a51449499b4daa977
BLAKE2b-256 551ea579e9bb82db7fbc1286afd84d80320d79d2e2887503506b972cb202dcfe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1fae0d79e166e0c7f189e98c70e99bee610273b190f1dab275532a3ffc9b09bc
MD5 7ee48c36541293400675723391899e8f
BLAKE2b-256 36ee98b14b49ce5c3858e2a01826500615db5074768677024de8392956d1488d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 23f8e113f43d104e88e4c13a956e8f9b17e86955266b0ea6b2b07c9ae4ad4eb6
MD5 a93a43d8470527c12ff7ce060e9b862f
BLAKE2b-256 de23a7e64a7389164f802a2e021bad8e01f2f14117893424fdf23bd89af2cc24

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fd7b6301dd15ff336617820c0a9541c616cc02a318bc626a8d06929c83258927
MD5 e42f33a29a534a30fd41619d75f95a06
BLAKE2b-256 40c35b9180e84dec9b50b99dc68c715e704cd27c587375ef3dbcf1c2c55d7ec1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1b32dffef1a6e6cfacd4787a82680be7ba997d8189be921207649e872bbd59ab
MD5 7b16f8d0244e5f86cfd80b0d70d96596
BLAKE2b-256 3b655e944ea7b2c18b6c30b2e56fc0286b88ca1c4d503cfd18f86881234b4ea6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 4b9391be2524b118f23748cfd23c7def60a63d44bc63b4a9abad6126fd0cc2e8
MD5 300fc24713e7b3fc5fcafacc2124cf8e
BLAKE2b-256 9c7c8cc5d030c53fc999f2b8d903f417dda2825588e2792749e67df26fa68db4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 50425c985fe149892cb6558a867772f408fdc058d909c867ab968d1e492f6cc8
MD5 ff9fa7b15a16fcf510e799ba46b3bc29
BLAKE2b-256 67b1c349b436dfdd17fdff245da065256c1978473dbcc25c6b3f575c31b0883b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 273acb132771513c858934f8e2738985abfd72cc063e176c638a28fbc2c337ab
MD5 fbd56386633bbcd4419c485a68fb9cfe
BLAKE2b-256 49ebcf0238298d5f6b7ba99da8e1b906a68aad3606cdf14da9833c879ae66629

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 eb3cb0f7d2ea9d0eec40a00e63636e07251973b8ffe1357f944e7a253ce793ba
MD5 ca4e5a2b9a97b7a36f7bec7c0284cc35
BLAKE2b-256 0254b0661e10111b762cd938cfe3be403b2438b91569f636dc02c0b62f95f4e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 267679f0145185f05edc0e40994bb1f82fa9bbeac2c1a957442884855fbd9ac2
MD5 39c0bc9b4f6416063a5aa903ad0d109f
BLAKE2b-256 a6986b5cac414be84b3b14e5a86b5b777b440a58ca38c2a43e5e91c90f225f74

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 bd8e22ce556bbb54b25ce70efb91b79f6573496b5f1ae0e7a11093e682d763f9
MD5 8c41a0d2ed1dbc4b905d3a86a343c5f5
BLAKE2b-256 612c1896da596b6735cf9e97e9fea02f6bd0719f9b31a1769400c588918bdc0d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c382fb1617273e4d92dd453eaeb1526039a0b158e5b1df706ae4b7cf7ca3077b
MD5 2b255b39eeae21fa701c586c4faa6016
BLAKE2b-256 b7b8b3343415139f42f2e6eca64528fe19c7f34aca4e1a9ad49ac196fe9f9377

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 3450fb008b707525e1304be217df2f7d2810c8e006b2070c3b8221efb49794de
MD5 342e48684018605f2ac6edbb5fa6ecfc
BLAKE2b-256 50405a75f30a949e21d25f873ac996a6cd3fd8bba6358c67e30c7ffed18b1193

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 87e2d71527d8d54e95038ea77849aefb169b79a2da5f3c48bb5a50ba781a86e3
MD5 84987209531f6eefab5b064008efe1f1
BLAKE2b-256 2ec4484a18d317fea46a82c47aebbc60efe85eae2be7f4666ffee09fc0c3b4ef

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 4bb307e86bbbab3f45e1f302a5c2353c6713b6c43be073ddf95683436ef985bc
MD5 1e0ba19ea64ffc978ff5d80fb2d0a501
BLAKE2b-256 794f859cae9c6f58d1194bcf6fb9b570fdebe3b9fae565bb6c82d14ffd643040

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1a4eac75a4baecd198ed17dfb4cc07defc4201a8045aaa4c025fd14747eaaa5e
MD5 efc103786b136ed5ac3fef2aeebdc81c
BLAKE2b-256 d4f664e502b00a3309be39350142d2a1b53cba95f1f2e1e8090dadb292c4770b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b5e543ae06dc2da903deb62d03e4bb8c119f495c9e519f554bdc3a09e64e9054
MD5 59ee5d3ef4549a7f3446264a6840ba72
BLAKE2b-256 52a2694178d6f97f5b21dce04149e9c9c1e521a3a7e5ed252d53140e0501a48e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a5ec11fb1464f29c015e9776978614ffc5f8dd72675880398173e2598602f4d4
MD5 6934c0b8f17027ee6c9963a1ffff5d4a
BLAKE2b-256 b6c1fbeaa7317c79a31862229c4325f3eea9d918d86c092f3c807e5d68115e84

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 46a59bced27d0a461db93f8bd07ca67c209dcb1341af030f6da47c6410c459d0
MD5 967a65a3861261dfd814039a2f21eb33
BLAKE2b-256 85b05de9d364683a468d70cc3c7759c32c82e3e92bfc6499cbf2bdb74980f511

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 abc5c8b7b5da9e6cb0535eb5a51255891c0208f8c1a6fc7ed250c6422fe77848
MD5 fb5f3b701d58aa63e46c1cf3183c7829
BLAKE2b-256 fa380c047f25bbafa7d43c12e2a78b3e9bdaa5e00599681924aa33a94c8d280a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d9c156bc8a14fbc025cedca32e4abf796ff9a42b0b104dfcddfdb9f4a8958a2c
MD5 29be57b009a2ab6a6fb9515dc7105daa
BLAKE2b-256 5866ee9877d90b9824c98c93669511fb056eb7fb2c504a159f1ed2b389d8856c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 57f3f7e749e38d1f573a2ca9ceebcca0fa82f1707d263b190e0af4afe250d8db
MD5 6f9ad779c0a87bceef7e58b8d8cb6d54
BLAKE2b-256 24f73d30817bfe2800f2508e470b09511589f130ef45b2141986a3f63d7c2eb2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 70096e66588984cc3049b0df2d76a38994cbb6e21a76295e99c2cbbf04aceb74
MD5 9f5cdf0a0b9b5f0a8758d32241e9ba1e
BLAKE2b-256 0dc36f53feb9bab9489a854ee8cd9fae185a7af9bbda89cfa37cf320b297c22b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 ef2a1a7b0f796cfb4b14e316af58ebe148731ae5a647df1afa8917b5d2d1b978
MD5 e9abc9c29327c28c3312d5cc261c04f4
BLAKE2b-256 37a71703cd2977317c97d4376fe261cac5ae18868cadb8b9ae1cfef98b2174c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 a9323e3f84cde84350b3eb6de5e0653877f5002c71b9a78de8c7e3148ed0d092
MD5 2bb0cef5c66264a6ea4465ac55391f63
BLAKE2b-256 3a6c11da6b33c0afce6b9b85d897e79550caa7ec34499aca45ce51ef80b97d1e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 4aec5415333906860de4beaa057dafb8c2a2ac82779d431b24f78bf167614809
MD5 fa17b79439afc00c856c27644e3d0129
BLAKE2b-256 32d1d6be4708729f5e6b08cf105428553e4e8b7e370aecfa9be3f877d67b30b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 acf840c3f7c3714e1f1f03ca658d5f4e241c4e89f0af4b828b8814316433dcb0
MD5 580389685fb28abfef2120617e26f1c4
BLAKE2b-256 14d2eaaa72496a2464fd4b4acc101a1adc817a9f85d060da10dc59c9112bcb76

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 f155d475d6fe847242fd370697ef2be2fe9d100b363b4bc5194ceb865d24db68
MD5 d077c38444e99429a974a912d8e34fab
BLAKE2b-256 1a1f1e6986a1c1d9fea31174dbcbcd2f4a3ff3da14be253852a01246053f5f3e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 2e38723cbbf18c862dc65f1b36ba695f24c967473c4aca1d4481d0531e17e9f4
MD5 2dc76485ef29b65a2abb20231866565a
BLAKE2b-256 0a90c9416df21056bb6ea956b71ce6b546ff59807e1004daf23b12b7c3dd76af

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c36014a8a366db3062f5094e97f3dac26b2714e4a3b9e33420622e49a0e96d4a
MD5 f1f8a8208607d32cae5c16dd9bfbff69
BLAKE2b-256 6d12e4c46277f276890b65c9eea6c3d954da173c9dc4eff392402e728b4f0faa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 704ed1e6ec1b6a5ba83bc331a1e54d626e11322e0647486ac7c2ef4733cc6df7
MD5 dc297c48d0f2c2ec2aea063fc19f42b0
BLAKE2b-256 36f5528b82fbadf8267256d38bd73bea96b1969efed5c73ac379f8a8794936be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b1cae6f22601d31028a3a18f577cd8cb48f5389a34e044a3a2f7d0776f70f15d
MD5 189472fbae8793bf95ff16e177a19f03
BLAKE2b-256 d90e88616eb2a4125ba5e402ed703db748e4cb7cd353ab11b69c28b97cc022d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 924777a338a1371f0a52f4e95e7a100cce5168df50951fc701a3ba0d52e80b0a
MD5 ce4e8d18b0929152016aa643d1ed7703
BLAKE2b-256 cc66f42ee9da3ea7bc554208cd0c4e5cdf1daa143cc00d9e247ec51c4d58dab7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 a950b03b5954b206e19eca847e3b31d15c29402e3120c61fb089ffeebdb94946
MD5 dea8c1ef91ccb6526233385fef061b9c
BLAKE2b-256 12d6ec65f940af2e3ffba7a7f4d1669737852cfb8347670a64bed2af25274c4a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cf83e8c289d6ec07970bcf62e7bf137259701f84edca302adff49375a30d138e
MD5 8b38943b24ee8da64c99c73ce82ec1d0
BLAKE2b-256 2b5051de47dc5a57dad2690923f7939c6a74fa0cedec3db1c3f8a44fddb81ad5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6946f23a595467b9fbf49ffdae9adb473f2cbb342228df34517d5f8a5c06fe35
MD5 6c886422a58e0cd1fe8aed6a68cb3c3f
BLAKE2b-256 7a470e8974bf38f4f0b3bacee53863582166eaf3708af9f9616fa9335aad1c75

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ab638f9a7f44280045452cbc74bcef7cb53d7f4b8cf61bf3c1b79daa724c33ae
MD5 9ae0a30298197e7d428e9043300a1791
BLAKE2b-256 37bcdaa1855e6f09eb0c08a3de579385644c4b71509c031de8595e2b4d34f3cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 ea55580a9072aea97d158fd3e7cecddd48f8032061328d8bb737fb50d2eafaab
MD5 d310587737793e0a838b13db7db3863e
BLAKE2b-256 7a6ef312a3c13c0b027a67fc518b4ac5a6f0afb24cbc20036b2293f1e0f00101

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.2-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.2-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 a6df3d1feb63f4078f15094217957f7c6a5a9d847637f946f04815c12ff1ad51
MD5 38415ee44df3578519af9e16471b9e38
BLAKE2b-256 7eeaf302db93479dba029e9792b481658affd7eb99643e2347a222a2f22e69b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e3495876065afdb64475ba9affa3fdb1b37375a2f82cf4735db89d7e502fa0f2
MD5 ad727d4c42639ab71299802fcbfd3c62
BLAKE2b-256 4b06b257263c79ab80c79fda74251b44b8731e6c1241d943c984d706a27b143c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 2f379eab9fd85b94fe2862ea1eca77ca8e5ad2eb9b0dd4bc84485f2cd83550ab
MD5 ae8184fb3aaba15936480ee5a2b92756
BLAKE2b-256 ce00c70974c79700372d70268806f62493b2306a1a0031eacb0c86c20fdd0a80

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 10db9894e67579a64956c37d301a8b4a0e91697aae9c24e214616a8b52ee2c7e
MD5 3e8b81d063344be19fe373ac4d93e2db
BLAKE2b-256 44744f048564403f4f042800aeaf78ef6e45b0426c5f1f5d2860218075f6c5be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 fb6862dda5412a3ad3136fabb684e5790508fbcd47c2d226880f99c23929701f
MD5 12386fb2481780be72f3f89956e9bfd9
BLAKE2b-256 24ef3dfe1da3c145731512c9cbf77ef18ddc1b60286fe7d9f50b7902b4d4874c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 9f6f8d703653a45a8414a9403dcb4557e8b4439f659c33933940daf1ffa46558
MD5 1ee485d3894de041d9bee95f72a0cee0
BLAKE2b-256 2777ae6d9f00b4b0fd142b09954f2b8a332ab422702f8fc02a9eadd7345db7e0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e399602594e52c50e7d09d22f279aa9b79d5a3761c9d85beecc1876eedfd2647
MD5 f37624658d10cf04df96adaf31b4e2b1
BLAKE2b-256 0dab28ff89d6774d00238a0e12ace82e9a97afbcf5992b46ef10ce9d06fcfb53

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 d08c4f29324053916a5dbcc169802b814545b9e46058f7f19ce9ad8024be09b3
MD5 e6a1354360054cd05848854270a7d255
BLAKE2b-256 07c9d10e36bc1d270437dbaebf182778aa796b2d9e332580dd0a52f92f2bdbea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 5c2805b636d4424d611e250e22ba6130bdac3a866e16d6509fb235d45ca44027
MD5 85c3325ce18014f0cbbeebd2f9da4364
BLAKE2b-256 af0e6fd38b967be8d97d8fc307093131f7313bb1c143151451e4705fb39624d1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4cfa8270aab3dfd9e60698f7117a363f3aa779cf31af8b5330e10c44cdf48563
MD5 a95b5b37903ec0ace5ae5aa4c7c6836d
BLAKE2b-256 a29e719ef550c1e9af9893a66fed157e31089ea36890ffe03cc2ea28295b91cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 2998ab409661a55443c66136ec6da8b7d977d475466dceae48bdde32270e9be0
MD5 545713f74d1fc0eae889509be2979609
BLAKE2b-256 d400fb8ddbb01cb7421e655c910aa76d62c4539b0edae9086a5af1412cb27dac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.2-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 f3ad8f63baae1a10fb270d06193740f8d7220d7ac7530be3ddf508a63fe6484d
MD5 33536f4532e9c1533151937b43eddf19
BLAKE2b-256 40e1d9b21086c26b3bc8faba00e27fd380dbb2d2480da4afc0f1b9c30ecf5e9d

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