Skip to main content

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

Project description

StringZilla 🦖

StringZilla banner

The world wastes a minimum of $100M annually due to inefficient string operations. A typical codebase processes strings character by character, resulting in too many branches and data-dependencies, neglecting 90% of modern CPU's potential. LibC is different. It attempts to leverage SIMD instructions to boost some operations, and is often used by higher-level languages, runtimes, and databases. But it isn't perfect. 1️⃣ First, even on common hardware, including over a billion 64-bit ARM CPUs, common functions like strstr and memmem only achieve 1/3 of the CPU's throughput. 2️⃣ Second, SIMD coverage is inconsistent: acceleration in forward scans does not guarantee speed in the reverse-order search. 3️⃣ At last, most high-level languages can't always use LibC, as the strings are often not NULL-terminated or may contain the Unicode "Zero" character in the middle of the string. That's why StringZilla was created. To provide predictably high performance, portable to any modern platform, operating system, and programming language.

StringZilla Python installs StringZilla Rust installs GitHub Actions Workflow Status GitHub Actions Workflow Status GitHub Actions Workflow Status GitHub Actions Workflow Status StringZilla code size

StringZilla is the GodZilla of string libraries, using SIMD and SWAR to accelerate string operations on modern CPUs. It is up to 10x faster than the default and even other SIMD-accelerated string libraries in C, C++, Python, and other languages, while covering broad functionality. It accelerates exact and fuzzy string matching, edit distance computations, sorting, lazily-evaluated ranges to avoid memory allocations, and even random-string generators.

  • 🐂 C : Upgrade LibC's <string.h> to <stringzilla.h> in C 99
  • 🐉 C++: Upgrade STL's <string> to <stringzilla.hpp> in C++ 11
  • 🐍 Python: Upgrade your str to faster Str
  • 🍎 Swift: Use the String+StringZilla extension
  • 🦀 Rust: Use the StringZilla traits crate
  • 🐚 Shell: Accelerate common CLI tools with sz_ prefix
  • 📚 Researcher? Jump to Algorithms & Design Decisions
  • 💡 Thinking to contribute? Look for "good first issues"
  • 🤝 And check the guide to setup the environment
  • Want more bindings or features? Let me know!

Who is this for?

  • For data-engineers parsing large datasets, like the CommonCrawl, RedPajama, or LAION.
  • For software engineers optimizing strings in their apps and services.
  • For bioinformaticians and search engineers looking for edit-distances for USearch.
  • For DBMS devs, optimizing LIKE, ORDER BY, and GROUP BY operations.
  • For hardware designers, needing a SWAR baseline for strings-processing functionality.
  • For students studying SIMD/SWAR applications to non-data-parallel operations.

Performance

C C++ Python StringZilla
find the first occurrence of a random word from text, ≅ 5 bytes long
strstr 1
x86: 7.4 · arm: 2.0 GB/s
.find
x86: 2.9 · arm: 1.6 GB/s
.find
x86: 1.1 · arm: 0.6 GB/s
sz_find
x86: 10.6 · arm: 7.1 GB/s
find the last occurrence of a random word from text, ≅ 5 bytes long
.rfind
x86: 0.5 · arm: 0.4 GB/s
.rfind
x86: 0.9 · arm: 0.5 GB/s
sz_rfind
x86: 10.8 · arm: 6.7 GB/s
split lines separated by \n or \r 2
strcspn 1
x86: 5.42 · arm: 2.19 GB/s
.find_first_of
x86: 0.59 · arm: 0.46 GB/s
re.finditer
x86: 0.06 · arm: 0.02 GB/s
sz_find_charset
x86: 4.08 · arm: 3.22 GB/s
find the last occurrence of any of 6 whitespaces 2
.find_last_of
x86: 0.25 · arm: 0.25 GB/s
sz_rfind_charset
x86: 0.43 · arm: 0.23 GB/s
Random string from a given alphabet, 20 bytes long 5
rand() % n
x86: 18.0 · arm: 9.4 MB/s
uniform_int_distribution
x86: 47.2 · arm: 20.4 MB/s
join(random.choices(...))
x86: 13.3 · arm: 5.9 MB/s
sz_generate
x86: 56.2 · arm: 25.8 MB/s
Mapping Characters with Look-Up Table Transforms
transform
x86: 3.81 · arm: 2.65 GB/s
str.translate
x86: 260.0 · arm: 140.0 MB/s
sz_look_up_transform
x86: 21.2 · arm: 8.5 GB/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 6 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 🐍

Python bindings are available on PyPI, and can be installed with pip. You can immediately check the installed version and the used hardware capabilities with following commands:

pip install stringzilla
python -c "import stringzilla; print(stringzilla.__version__)"
python -c "import stringzilla; print(stringzilla.__capabilities__)"

Basic Usage

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

from stringzilla import Str, File

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

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

Basic Operations

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

Advanced Operations

import sys

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

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

Character Set Operations

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

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

You can also transform the string using Look-Up Tables (LUTs), mapping it to a different character set. This would result in a copy - str for str inputs and bytes for other types.

x: str = text.translate('chars', {}, start=0, end=sys.maxsize, inplace=False)
x: bytes = text.translate(b'chars', {}, start=0, end=sys.maxsize, inplace=False)

For efficiency reasons, pass the LUT as a string or bytes object, not as a dictionary. This can be useful in high-throughput applications dealing with binary data, including bioinformatics and image processing. Here is an example:

import stringzilla as sz
look_up_table = bytes(range(256)) # Identity LUT
image = open("/image/path.jpeg", "rb").read()
sz.translate(image, look_up_table, inplace=True)

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_archive = Str("<html>...</html><html>...</html>")
_, end_tag, next_doc = web_archive.partition("</html>") # or use `find`
next_doc_offset = next_doc.offset_within(web_archive)
web_archive.write_to("next_doc.html") # no GIL, no copies, just a view

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow import foreign_buffer
from stringzilla import Str

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

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

Quick Start: C/C++ 🛠️

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

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

Or using a pure CMake approach:

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

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

Basic Usage with C 99 and Newer

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

#include <stringzilla/stringzilla.h>

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

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

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

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

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

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

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

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

Basic Usage with C++ 11 and Newer

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

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

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

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

haystack.end() - haystack.begin() == haystack.size(); // Or `rbegin`, `rend`
haystack.find_first_of(" \v\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?

StringZilla is not a drop-in replacement for the C Standard Library. It's designed to be a safer and more modern alternative. Conceptually:

  1. LibC strings are expected to be null-terminated, so to use the efficient LibC implementations on slices of larger strings, you'd have to copy them, which is more expensive than the original string operation.
  2. LibC functionality is asymmetric - you can find the first and the last occurrence of a character within a string, but you can't find the last occurrence of a substring.
  3. LibC function names are typically very short and cryptic.
  4. LibC lacks crucial functionality like hashing and doesn't provide primitives for less critical but relevant operations like fuzzy matching.

Something has to be said about its support for UTF8. Aside from a single-byte char type, LibC provides wchar_t:

  • The size of wchar_t is not consistent across platforms. On Windows, it's typically 16 bits (suitable for UTF-16), while on Unix-like systems, it's usually 32 bits (suitable for UTF-32). This inconsistency can lead to portability issues when writing cross-platform code.
  • wchar_t is designed to represent wide characters in a fixed-width format (UTF-16 or UTF-32). In contrast, UTF-8 is a variable-length encoding, where each character can take from 1 to 4 bytes. This fundamental difference means that wchar_t and UTF-8 are incompatible.

StringZilla partially addresses those issues.

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").front(2) == "2"; // take first 2 characters
str("a:b").back(-1) == "b"; // accepting negative indices
str("a:b").back(-2) == ":b"; // similar to Python's `"a:b"[-2:]`
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(sz::char_set(":;")); // Character-set argument
auto [before, match, after] = haystack.partition(" : "); // String argument
auto [before, match, after] = haystack.rpartition(sz::whitespaces_set()); // 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(sz::char_set(" \w\t")) == npos;
text.contains(sz::whitespaces_set()); // == text.find(sz::char_set(sz::whitespaces_set())) != 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_set()).rstrip(sz::newlines_set()); // like Python
text.front(sz::whitespaces_set()); // all leading whitespaces
text.back(sz::digits_set()); // 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(sz::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(sz::char_set(""))
  • haystack.[r]split(needle)
  • haystack.[r]split(sz::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; // Expensive to construct - due to system calls
    static std::mt19937 generator(seed_source()); // Also expensive - due to the state size
    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

Bulk Replacements

In text processing, it's often necessary to replace all occurrences of a specific substring or set of characters within a string. Standard library functions may not offer the most efficient or convenient methods for performing bulk replacements, especially when dealing with large strings or performance-critical applications.

  • haystack.replace_all(needle_string, replacement_string)
  • haystack.replace_all(sz::char_set(""), replacement_string)
  • haystack.try_replace_all(needle_string, replacement_string)
  • haystack.try_replace_all(sz::char_set(""), replacement_string)
  • haystack.transform(sz::look_up_table::identity())
  • haystack.transform(sz::look_up_table::identity(), haystack.data())

Levenshtein Edit Distance and Alignment Scores

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

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

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

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

Sorting in C and C++

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

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

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

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

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

Standard C++ Containers with String Keys

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

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

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

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

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

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

Compilation Settings and Debugging

SZ_DEBUG:

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

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

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

SZ_DYNAMIC_DISPATCH:

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

SZ_USE_MISALIGNED_LOADS:

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

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

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

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

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

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

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

Quick Start: Rust 🦀

StringZilla is available as a Rust crate, with documentation available on docs.rs/stringzilla. To use the latest crate release in your project, add the following to your Cargo.toml:

[dependencies]
stringzilla = ">=3"

Or if you want to use the latest pre-release version from the repository:

[dependencies]
stringzilla = { git = "https://github.com/ashvardanian/stringzilla", branch = "main-dev" }

Once installed, all of the functionality is available through the stringzilla namespace. Many 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 can be added as a dependency in the Swift Package Manager. In your Package.swift file, add the following:

dependencies: [
    .package(url: "https://github.com/ashvardanian/stringzilla")
]

The package 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.

Memory Copying, Fills, and Moves

A lot has been written about the time computers spend copying memory and how that operation is implemented in LibC. Interestingly, the operation can still be improved, as most Assembly implementations use outdated instructions. Even performance-oriented STL replacements, like Meta's Folly v2024.09.23 focus on AVX2, and don't take advantage of the new masked instructions in AVX-512 or SVE.

In AVX-512, StringZilla uses non-temporal stores to avoid cache pollution, when dealing with very large strings. Moreover, it handles the unaligned head and the tails of the target buffer separately, ensuring that writes in big copies are always aligned to cache-line boundaries. That's true for both AVX2 and AVX-512 backends.

StringZilla also contains "drafts" of smarter, but less efficient algorithms, that minimize the number of unaligned loads, perfoming shuffles and permutations. That's a topic for future research, as the performance gains are not yet satisfactory.

§ Reading materials. memset benchmarks by Nadav Rotem. Cache Associativity by Sergey Slotin.

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.

A better algorithm is in development. Check #173 for design goals and progress updates.

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.

If you are looking for more reading materials on this topic, consider the following:

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

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.10.0-cp312-cp312-win_amd64.whl (79.2 kB view details)

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.10.0-cp312-cp312-win32.whl (68.3 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl (288.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl (203.9 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl (226.9 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_i686.whl (209.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_armv7l.whl (197.4 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl (222.2 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (294.4 kB view details)

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

stringzilla-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (201.9 kB view details)

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

stringzilla-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (230.0 kB view details)

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

stringzilla-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (226.8 kB view details)

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

stringzilla-3.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (208.1 kB view details)

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

stringzilla-3.10.0-cp312-cp312-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

stringzilla-3.10.0-cp312-cp312-macosx_10_13_universal2.whl (121.3 kB view details)

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

stringzilla-3.10.0-cp311-cp311-win_arm64.whl (67.1 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.10.0-cp311-cp311-win_amd64.whl (79.1 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.10.0-cp311-cp311-win32.whl (68.2 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl (288.2 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl (203.4 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl (227.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_i686.whl (209.9 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_armv7l.whl (196.9 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl (222.4 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (293.9 kB view details)

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

stringzilla-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (202.1 kB view details)

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

stringzilla-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (230.6 kB view details)

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

stringzilla-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (227.2 kB view details)

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

stringzilla-3.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (208.1 kB view details)

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

stringzilla-3.10.0-cp311-cp311-macosx_11_0_arm64.whl (79.7 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.10.0-cp311-cp311-macosx_10_11_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.11 macOS 10.11+ x86-64

stringzilla-3.10.0-cp311-cp311-macosx_10_11_universal2.whl (121.1 kB view details)

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

stringzilla-3.10.0-cp310-cp310-win_arm64.whl (67.1 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.10.0-cp310-cp310-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.10.0-cp310-cp310-win32.whl (68.1 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl (285.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl (200.3 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl (224.4 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_i686.whl (206.6 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_armv7l.whl (193.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl (219.3 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (290.4 kB view details)

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

stringzilla-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (199.2 kB view details)

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

stringzilla-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (227.5 kB view details)

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

stringzilla-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (224.3 kB view details)

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

stringzilla-3.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (204.8 kB view details)

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

stringzilla-3.10.0-cp310-cp310-macosx_11_0_arm64.whl (79.7 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.10.0-cp310-cp310-macosx_10_11_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.10 macOS 10.11+ x86-64

stringzilla-3.10.0-cp310-cp310-macosx_10_11_universal2.whl (121.1 kB view details)

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

stringzilla-3.10.0-cp39-cp39-win_arm64.whl (67.1 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.10.0-cp39-cp39-win_amd64.whl (79.3 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.10.0-cp39-cp39-win32.whl (68.2 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl (283.8 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl (199.2 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl (223.3 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_i686.whl (205.3 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_armv7l.whl (192.9 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl (218.3 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (289.0 kB view details)

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

stringzilla-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (198.0 kB view details)

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

stringzilla-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (226.2 kB view details)

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

stringzilla-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (223.0 kB view details)

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

stringzilla-3.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (203.4 kB view details)

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

stringzilla-3.10.0-cp39-cp39-macosx_11_0_arm64.whl (79.7 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.10.0-cp39-cp39-macosx_10_11_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.9 macOS 10.11+ x86-64

stringzilla-3.10.0-cp39-cp39-macosx_10_11_universal2.whl (121.0 kB view details)

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

stringzilla-3.10.0-cp38-cp38-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.10.0-cp38-cp38-win32.whl (68.2 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_x86_64.whl (282.7 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_s390x.whl (197.6 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_ppc64le.whl (222.1 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_i686.whl (204.2 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_armv7l.whl (191.8 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp38-cp38-musllinux_1_2_aarch64.whl (217.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (287.8 kB view details)

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

stringzilla-3.10.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (196.7 kB view details)

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

stringzilla-3.10.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (225.0 kB view details)

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

stringzilla-3.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (221.7 kB view details)

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

stringzilla-3.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (202.0 kB view details)

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

stringzilla-3.10.0-cp38-cp38-macosx_11_0_arm64.whl (79.7 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.10.0-cp38-cp38-macosx_10_11_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.8 macOS 10.11+ x86-64

stringzilla-3.10.0-cp38-cp38-macosx_10_11_universal2.whl (121.0 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.10.0-cp37-cp37m-win32.whl (68.2 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_x86_64.whl (281.2 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_s390x.whl (196.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_ppc64le.whl (220.2 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_i686.whl (202.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_armv7l.whl (189.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_aarch64.whl (214.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (286.1 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (195.0 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (223.2 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (219.4 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (200.3 kB view details)

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

stringzilla-3.10.0-cp37-cp37m-macosx_10_11_x86_64.whl (78.7 kB view details)

Uploaded CPython 3.7m macOS 10.11+ x86-64

stringzilla-3.10.0-cp36-cp36m-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.10.0-cp36-cp36m-win32.whl (68.2 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_x86_64.whl (280.5 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_s390x.whl (195.8 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_ppc64le.whl (219.7 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_i686.whl (201.9 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_armv7l.whl (189.2 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_aarch64.whl (214.0 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (285.5 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (194.1 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (222.7 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (218.6 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (199.8 kB view details)

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

stringzilla-3.10.0-cp36-cp36m-macosx_10_11_x86_64.whl (78.5 kB view details)

Uploaded CPython 3.6m macOS 10.11+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 e23678c46be94f65e11fa12d68e628024c6a72513608eb1fe9025d79408a5003
MD5 121c567734df44535099c66e931c50ba
BLAKE2b-256 843fe1e1d843fb05699010d3ba6157dde9103d964323cf14e7ab9445af775f6d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2e00862c035256374a3b05a3fe280650d62e496d6b81495d516072adfd2e564f
MD5 a2ef58f00ccd950b2ae13e40c9b2cf0c
BLAKE2b-256 b3ba68576d2950c8c600aa2c6417fc8cc37c95f2d4beb3b79014e97c8318ea92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 9f8dec99452034a4517c87c9346d8b4593577458b37716f7579cf973451d68f0
MD5 a2a2fd284099b5baa055c84fa8715e79
BLAKE2b-256 ed17bc3a39f68ab9cca3eb6f729efe7808d7d63e8c0313ef09ae6faf37e9c59a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 68a9a94c415712564ed64c1b9eda59fe5fc7d4217aa44149026e3703eb5a622f
MD5 fcc99038576ad895ee77dc44c2a06569
BLAKE2b-256 fd5d07b67a75592a66437db9665a6595236e939e31d8f4b99d20217494989a3d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 804623f603c9f2cc1ea2c6fcd18c6727cdea44f8b9c634e00086d5a998f562ab
MD5 47dcf1f6564b394ec228e415504b0035
BLAKE2b-256 cdd5b998eeff7d2adf5a05cf574a76acda268e4d74b408a7e18a30527dc6e859

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 1bafdb563930d1e01630d6e2e1d60ca830b6f6a0d1304e231b5a1ff7d24a2710
MD5 9dbf264df853ec8802906d285b1fa9a5
BLAKE2b-256 e285a463bc91b1c1f0905db9be9e63fb30f7c8916108eb3f38c5467339134aae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8269b248586fc289b81b2c270cfbc81d72f88e76d74d9daa8869b2ffac9601a9
MD5 ff725c48a4e0345ebaebaf4f66908fc3
BLAKE2b-256 345d0ee8553df856ab7213c5c5cc9d01cd9e1a66aba593f5a5042bede517120d

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp312-cp312-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 a6b0805fc7fbaf52be59ac30ab32be8af069096d719ff73574a8fa09a697c501
MD5 b35efd95cfff08a2e9fe4204aa82af4b
BLAKE2b-256 c49c9ea34c4a5e560a92f9c4ebb4fa2b1364f89a146f45f474ea9e9fa70ea6b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b786f01c69fb506604f3cda4ef2b1af26af04422cbfb95694dd6203fc54a4e0a
MD5 71f4d75e1d71fcb4b6b1d7835e395968
BLAKE2b-256 51ceebbc0d580b34ba942cfd5b89a9dc7c42ad7422604d1921410b620eedc836

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bd3227268fa872834dc176cc3484f3a8c72e69928cd573c5c14895f561d54dd6
MD5 dfd63203778a145b085c9790e7195fa7
BLAKE2b-256 5a0e9747316ced20b3d6f7c8857c42a5464196cadb3a76442faac669bab46205

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 de0a2b94fa38e99204fbefe88ced1ea70d6939ca68fa05eeb64e1a3781e00c31
MD5 30cd24823780698c787e23e4397ebce0
BLAKE2b-256 3dac8a2d8cae8b3bb9bcd61e8d764381e9e3c487ca95ba91a26064c1fd51039d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 6b283b13ea6720d3904baa74141e37e1ef7616b5a70673c2ec080933bc11ddef
MD5 1e9eacde00ffaa99d60396424daa1017
BLAKE2b-256 698e73178db765804cf3eacc5a9d5387806543ac2c9c4a3b6c50b858d8d24d1f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e7b7646a3670c12cb003dfffe37701865ac7ddf505932ff092f7eb684ada229a
MD5 f9a481d7b068e44414e5d8c13c78cd77
BLAKE2b-256 73b86c0aeae071716f8e8075ebea035bf5d8d27115315c00ca53bd7b1ab004b9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d1631951735fd1722302bc949128606741c7d5978cf6bda2dca23af750d110ee
MD5 2fb52aeed780524aa9055a7a9026e316
BLAKE2b-256 08656467e2b85ec68f16431dc75013380f2756a1c0f59632a62b30ced50897dd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6fffed9512b8832cf360a1e092c81e685cd07d044cec418148e789e77d72a546
MD5 7d2aa5a238f892755c189ef13a033298
BLAKE2b-256 d620623ae23ddfc0c8c79e9261779900285310715d460b8d12b290fa37f682e5

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 83b545116fb5cedff22a772232ef9e0e8ebfff0a3c7f542a1d96ef8f8d08b4ed
MD5 4aade374931cd91709e97fc47fef83e7
BLAKE2b-256 a2bfc8c84a81fc56dedac218af07a47ee8a1ad9a6b8d92276a3ca5c7915ebe37

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp312-cp312-macosx_10_13_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 bb0936c1b9c645b36455a8b1ddc2616a8b10f7c4b4ec6d224577fd580b00d67d
MD5 e4e640fc087cece282047d7eb3b60f1c
BLAKE2b-256 3c346873ba68a3acced7c4c6fc95b1027b0f7bb896c581321ae4cadc595febe5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 58c5f1074a6995401c558c3387c4f3a0e6e707edabe172c3398382c3fd00a35c
MD5 06d9e0f6bd5bb28cb08f3147164ba6ff
BLAKE2b-256 5ee6bf76c35313ddebea3edb15f144caefec500145e3e031b5012db835565960

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 aa9ff13fa60fbd878b8a3a978266127268838c0f17925de313e9542ff60f02a8
MD5 d066b96217f3b6b984c7f9707ca52203
BLAKE2b-256 c4e53104d4ceca58dcb829a960010f7832c99f684ee167be8c38daf966e3db3e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 a3cb12d199a938d7d75bbf7e96abe3d5b91fbbee4a0769301f9e2d3fd0a39d59
MD5 3e245e76fcada9eb34d49908b919f688
BLAKE2b-256 8c8d8dc4811427e1288671aac63e68d4fcfc9e57765517133d3b152af9a556d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cef8235846b3a97470dbcad37ea8ea4ca12a55cdb8ac59ff0bedb03ee071145c
MD5 9d5706494557e5854a8961fcc03c271f
BLAKE2b-256 a1edd41a8d1fb0396a95386c41cb1e84ba4023417c9c9ca4c8f3b6346765e6a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 73aa17ccdd000fcd108eb0d03e2319ab20bada0c6f728f543858f8ef1cc0329f
MD5 6be9b8bcea4cc72af9ba596409826540
BLAKE2b-256 b99bc3a5de4493bd106901f0f9dd37a18971e206566e1aa1e37fbb2ffeb63866

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 20a58c0e4d20cbc73a0b6f545996491a28bba07fc02e5e5db8dce5840f2401cf
MD5 a67bbc553b924a50622b8eb90e6fcc27
BLAKE2b-256 797f6f10a6f8fb7250f1b7b93b1c845f7b5622774c6a836459253a3465dbe6f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 d937744b8fd6e152b81c5a4ce1f0007833037660044ff9814595b30a28f8793c
MD5 9bc09c41d55d581bda47c65d74886044
BLAKE2b-256 160a4c9369ca692cae5dc383ef26b4997ad5579d15eb2aff0b9db13ab2abded8

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp311-cp311-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 3c9ebde3857accab43d6ed01a38f0efeb35a3ca43db13090b94fbdb923cb0662
MD5 094b7b5112658a519d5a10f63a4dba86
BLAKE2b-256 89d0c9785321995c004ba881f9e2a6a3d0e322b09bc15e092066859300b4f758

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 bc49a396d60f453d5be46d5db7fa87b8ec36e724d47ea5243bf2c6ff834fb856
MD5 51cba19a3b87e847c5e4a7fea7620f91
BLAKE2b-256 1cb5891b6270c67de9500e368b94278aea0a6d11ccc0a8076912208735f7c30f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1d2fe1ff479e464a48ad5e61854dabe72c2ff47b74f9e96f6eb04113faeb8731
MD5 0ea3d46a7541642c5f0f8ed6642821ac
BLAKE2b-256 ab6c46c889c2e13e368e4b0354b15746cdc244c570eb4bf9d356a81d337be87f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 1351ff79fe473623a57ad65ac1d648e816be5f2195526982ed9d55aa3f863c00
MD5 8be7ecdcf39d5cd2fb832671f454a31a
BLAKE2b-256 39a50dde47cbf03e8c7b4296f414178e81416e65e6f45dff5e56beafa046dccf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 496d0243df4cf023291308a0527d0ae918f127ba02eda0c69b09d27ccb59fb82
MD5 325d9f671adb9c50d685cb62629c1b18
BLAKE2b-256 7127f92e405751c3cd564077a7be0515114d211f0606d260c3af407753a7b8bb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ab6919810199fb9f535af6fe3c0206a3910e16f734af6191c43a89d1c04e7b35
MD5 1134da7c2d37005357b974ca643c2be3
BLAKE2b-256 82a7115c492025be33e4f96004e867a0303ff15b4226c4a8c3cca6c8fb60b3f5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e422d603cd12dbc68a465089c6c693dacdec66ac244d02135a118efd7f0cc9b5
MD5 2b813019a4ced96ea356015b86635105
BLAKE2b-256 524dc112f137fe9cf7bb26556f862bd0996bf5b03bd603277c18dcb18ee1d00c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a4145a49d478dc02a5da5593a5cca7d00be1ba84b76afef46cb387929356d288
MD5 bb6ee9118b28c4c42969b19db2b8be88
BLAKE2b-256 85072e958512511dd4200d743658e421f0c598092f38f314b633534c00f9a0ea

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp311-cp311-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 1b24eac178a39cb60c372ee2c92eb87eafda2b6b8d030973228299805559c621
MD5 58d5bf408a8db2e4c3a6ef29d0532ba4
BLAKE2b-256 12c2fdea111298f6ccbac6abbd97aab604b4e03954e894c0f99b26dda2c6fc98

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp311-cp311-macosx_10_11_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 a37c1173cc82ad341a986269255dfac30162d11c686c4dd7a0f42f1779563f79
MD5 e800533467c07feeea0457711bf72f74
BLAKE2b-256 b0414745f03b22dc5e8a0a9e281cb443e9e5bad1abde43f0dc3f06192d05482a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 319c016e86bd61b236bc82c1d7ccab77d377cc3176f96d5c33d8036beafbbbee
MD5 293a7740600ae181635cb376b337f576
BLAKE2b-256 86cfe5625b6cc0a1185aae6db08793a2fed1c277b5b7b08abd8ca27eee9d9217

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 23754af798d18b8f5c97dd8b36e0a7cd6e2cfa0feb54e00aebe5d1a4f1fdfeda
MD5 4b4b681104222965d9903744455ade1f
BLAKE2b-256 895a38896a635e10bd3e3633b7f38f459cb1692418006aa60bf33908b0125d58

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 a7ed4de099e2b10677678c735614770f989dc7a6c99635b2ee79bff5eefbe26b
MD5 d3388dc1403fdcbf5bc3aaa8a71059b3
BLAKE2b-256 4574d16ccbe8764eae7ff9283abc5377f5b59e6415b4da882ae98c6cda68932c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f47a5441c6f3f6513fb01b08ef0bc231ec44bc746fcaaf3b10c2a50d77a80765
MD5 acfc0bbdce991984cd51b7273a775610
BLAKE2b-256 39430837d16eaf22bc7870894eb83cd6f18e52b9e45ccc4499e330a276ae24c3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a14a9bc73843b75acdc815a17d2c83e994f4f9bddd76d2bbf4f8d5c9ffe4c9ff
MD5 89793fa5fe1dbcead119fb5d13f5a87e
BLAKE2b-256 20df5c7a65a815521811d6e9d0f72172c9c055c594bf96eb86db2cd8c75b237a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 836fd104ae0ba0f54864a17ad64fa0a0a0022f4779d670463985724d9bcf8ab1
MD5 308c3612689d0088c54a48f33a3bcdbb
BLAKE2b-256 665b023a6799fb97bd58dda14a991b1975a5b3f1a54fc8a1c04e552a572d203c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 4ba4eb727924436875ee3dd44ea2d90c5e009fc894c922685843a0180d795e9d
MD5 b4a33f6e1096e0ac36b306da5c5c1007
BLAKE2b-256 cb51329e03923f25bd8e3c256f79428a11b2ba4ab089a8ca45b78409411ae8de

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp310-cp310-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 0447ee3cd5f99555690caaa6138f386ad3f1d4f9293a5423d3c5834c0d2c0989
MD5 eaa248d3a4b640d23356c48eeb773e49
BLAKE2b-256 4951f49d32f39f5d5071a9231f14d8186ed72106eb789c55ad77e5a7aabca490

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a0a2ff54e6082f7404f6fa40fca20ba3ffca4139cadae2d6bb20d08a896db1c0
MD5 d819bea1442df27a4a7bf239d95122f7
BLAKE2b-256 be1645d8e5513cb2cc328a94a058cce9d58cb9134941fd698da61dd1d4033075

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0cdecb910f514df4b7c6c05dc4cf8ff819bda7cc4ed99a50f73b0055b08c6ca0
MD5 4ea78bf39ac7c88c4ee71ac1fb5942b5
BLAKE2b-256 75af3c99c6aeb548b1239d41a2837168c1f55addaafed2576dae9f48eb679b6d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 6e4373236d803c5fb361384b3cb4f87e1a234e75cacf926fb4c289802179152b
MD5 d24dd929bdaee31fdc5a8f7de257938c
BLAKE2b-256 c00a41cefce8f6fdadbbcfa8217335fe3809fce793765dcaf1bfb39812540eae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 15cad0185a51cc5d920e58ec0cfdfee541179dd3f13edabda12500b881b78f57
MD5 d9426b4977ba8a7678020b7d0d0ec34a
BLAKE2b-256 cfe1d047b8efbbd9751331c70687f1367366ccd9a9863fa6f27f24f299c6e89a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8d3bc3d6382145a7e11ebd73e297201057d1abfeba719800cf162759d946b38f
MD5 d5ffc8fdca64a1c24a584e8dae06c74c
BLAKE2b-256 933f3933ba50f70d3429cbaaaf2ffd96d23ac2857d232485d48ea8f025b15684

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ade90afa096f9551a44fe2de57073f5d51391ed860ee9db643586ac30dede162
MD5 df2ef05e7c146185f62b99d5da37dcb3
BLAKE2b-256 f4ec9425ba8c36cefd0070e1efb34d0d7be82822110ec8cf409479dde887e7f4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7fb796b8285d8d4ff3d44abd449c624f6dabc32acc46814ea2e5c25263dcf750
MD5 67fa9ef739d0901ab5ff7168532d3bb8
BLAKE2b-256 81576a57326d8aadde31a0e2616244f8b23d9eb0c3eb272feb60dbce7ac106fe

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp310-cp310-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 ee6f31579310eb999d7b235268562be9dfb94160f5a957c7f103f873ef3c53b3
MD5 e1beacf07e53db4af33c4e70c0dc43fd
BLAKE2b-256 43ae430ef8045795182214d528d1f6ada9c33d5d056d0c940393b5ebd9a4925e

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp310-cp310-macosx_10_11_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 8a016076d777c132014eb91c67ca349a530103d42c4f4f08805ebb3c54810b7f
MD5 1ec4773b79d321c687a0777d717ea025
BLAKE2b-256 a0e9ed60b586f77146b094ababe746530fb44ea4ba43637251930c2523bd7f3c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 38857e7416568d0e888e1c19974a6b86dc82912550882981b89fb82ea68f9ed4
MD5 48683b534b437eea9df71b986b6e7005
BLAKE2b-256 59f4fe1d41f0b1f56f18cbfb20f841a95f5ac60892e1642300d90c652ceea8b7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 1d10569118682c67f02ac2eb8b3733fdba01f2b73f58a4501082fd58b3cec712
MD5 e7df61a38a861e27073680789dab3729
BLAKE2b-256 ac1ec1f4ce4c7d62d8431b48d25d593816f9c6600c3136f90f44e082f3bbe09c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.0-cp39-cp39-win32.whl
  • Upload date:
  • Size: 68.2 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 80736689110201b475a242517c2e10422a169f924f48e11919ce67a5b64d5556
MD5 eacb12f6f6e07e0a4b03c209f4b31d6c
BLAKE2b-256 d39bab907e2cb371757aeadb6ec32871112838542f30fefe1ce55366aea655a8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8c443d84347489468a34e211418ca2ab915a4105c3130721795ef2563bea3079
MD5 f2e3e2a104e70d76d670bd81cbd14464
BLAKE2b-256 2ab9f658d430e3800d826c7164515b4ed6196f43803532f944808bb1f040d932

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 3cdc0f35e681536857c075c68c02fdf3fdb6c5e760123ea2c48e05513dd71fb9
MD5 bef3c3b842d0733488121111ebcbc4f6
BLAKE2b-256 0e3c33d9b6dc3d372e2af2c050e9f57f8740519d839af13a45ee5ee86006bf1d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 72e1039f4eafd31bd46dd50fd11c9974e4bddf357dcd53f45a97cded560d1e2a
MD5 019c71096bcc79574463dca7d957a5fc
BLAKE2b-256 0bbc7b4a9467c1e90a4144f256fcf9add6f270fadd97cf8f8de02e8a049d780f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 d879a0c3ce0795d0f849cbe4900738247902b69f1c91dca303f7335da7662343
MD5 9476b80dc6a4b359014deba44795c150
BLAKE2b-256 1ca04718f0d3d5fe653f18e53a2679cf631608ac54250d825e5e949ade0cdd58

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp39-cp39-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 4823edd881d232ba51f718b528a6430c3d13d04a96143ffc2ac892e690d06b53
MD5 f841dcc8ee14a8ffc752d8f4f63bfac0
BLAKE2b-256 dd44f0042a999062718d209ab179ccc8362843d0b24b04523cfce165f5930dee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ec3b676b27cbfea6366aa3c735cbd00d610d68552593e1f6bd7608e20623e929
MD5 2a64379587f7391e8b51f23130e742a4
BLAKE2b-256 16be5a34e467e3601272b5d7846fbe24540109583e73b4a41d7a44838e557f14

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 120c87a28d71e3db96d8a4edf6adc348aadacabd6e1d9cba452d0c770e064679
MD5 f1ef8e25dc061960f282b6d872e5fd37
BLAKE2b-256 4ff6f76b4880695a74213335813b9cb29f665b6b6ab64b592d2ec6488e79cde7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 525f6d8d1975e8a5e597909f58175c49ba46ca2b66c8e19a711d5a1224905ef9
MD5 92f6947a03290ef9398c02d08fcb9e0f
BLAKE2b-256 3431ae61f3a42c9aa41fb5ca3c0377ab718a10d107490488696bcb6109f6220b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 0187d5828d286b25dba82fd74de3d29d47294474fe8b0545e035d8f50d1149ef
MD5 7d341133404abe5a938c26a684be1f50
BLAKE2b-256 781f648d0a81989b3888405d37dba359c43a8ec5906e2297db23f17ebcde0551

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d7d728bd27a8bfa0d44f62515646158acb7746020131ab57a7b6f2fa597e40a4
MD5 adf6379f3301f22701671dc656c71ea0
BLAKE2b-256 9b4437147dce8ad819a0ff167a509a8f51f31624abd55ef33fd39048916ab6aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1c8d2c459b1039ec53c9576df02978027dd6407786131c9a3ba1b33a4c640858
MD5 9503137c19ee70ee518071fc6efe8c8e
BLAKE2b-256 4c6a6a8d87b1d876d4d0767efbd271392831abc39dbda043f5ae3c4c614a6a23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d41dad6a2facdd0fe3da6b54ad65b07546bd03db21e3ec7a23752b0438e5e2cc
MD5 f9da1c0a969d4fa8e7dfa862e4419f77
BLAKE2b-256 e0ed5b5311b6494f555acd94d292a10a110bca5fad110a24bc4f461ee54f0d2e

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp39-cp39-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 d7deed8e67b5bb3908e33d5ed4c69b50500bbcbe3aebab3018de2d763625d353
MD5 299ef532e0fafb1749222b20b4e7cb29
BLAKE2b-256 2a67a524fb5e8fda9e295f4b59bdabf0c561f34b22876c06efe8b31dc7329820

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp39-cp39-macosx_10_11_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 d8d32800d87833b1587398e836a16aa16814c353f4b145d19eafe3099282646b
MD5 2250154bfabe7af8b8daff2629c48a9a
BLAKE2b-256 784389ebdd9e309294f92f4881324e55b06b94e6bff7dd2b82a2b446ca93ce3c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 d9dbd4bf9d42a7b0c0d590f898fa3802be6d1c883a3cc9cf4482575bfb855b4e
MD5 6da27dfa417ad37adad9622aece181e3
BLAKE2b-256 c44c9e641c90752de4bf11f38a2331d20b8f41bd6981ca490562b3c078fa82dd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.0-cp38-cp38-win32.whl
  • Upload date:
  • Size: 68.2 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 f6526fa8eae6e81d602e29c53626e1494e1b54c2d77b69863e2ec7c6684cc8ec
MD5 5bc1e8bd2b5880e1565b193d075b1126
BLAKE2b-256 d786ed410647df1a6d4cc3f7b13a3b2fc0288b88efd2ede123289247fe42c190

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 57c3fcbbef99aa7e35f2f01b99f55dfb6b4a5be1734242d08c4eec8f94635164
MD5 b3bc3454ab1b36a115f6a731764206fb
BLAKE2b-256 af2e70e559c29aa261f8ab2c1c6597babde55df8530ea1fd50ce1d7362578166

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a80e0c743914bab86edfc479989cdce34e2025845760969e349a4544687b44ed
MD5 fd222ebbffc23579cf3ba29e60b2cd40
BLAKE2b-256 7fe7de624d283e6f2dd5101e35c23bad6e7479ebc0fb1f688cb4088c9cce9493

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c3e066813cf4074883a0d425dfb278065b8ffbcea94d5bfad70952e17ea3a26d
MD5 06d0ca56bfde68db9f428ff6ad63234d
BLAKE2b-256 b5de94f97353c04d62c291f5b803541522da84fb3f7b152d9097a951c3c0fdc5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 09269867ff7b0d32e1ad9260598c49b939ae8f4b60109934dc8955a62d726eb0
MD5 54b9dae29bb1ef5a08eb0571deedaac9
BLAKE2b-256 8394aceb61964f40ff77815fc5a1c5f96f4e6c4c4c3433cae4566372c78c9f78

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp38-cp38-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 485b98c78a62d9a462726511bf75bad7de1551ecc94adc5e50128aa84b995392
MD5 6bef5fd918d609d019064500e8c5b713
BLAKE2b-256 567ae6c71fee02bdb4939225bec1f9029fb496937186dac4eedbf886f889934b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ce65f27411b823cb42bc0bf2d3f2798efccdd3e4bf5938331050af7c27adf160
MD5 542f6a1738f4b77a40d9ddbca715b88f
BLAKE2b-256 020932edf6287accf58396b17cd624f9a601caf902d6fdd708eddb9a6c8799f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b8aeebca1fa80e4f70ae8a4cd265f513be00e723a8455e95d6142b01db90df3f
MD5 ec10b4fcaab5440a1c42ebabdfcd76ee
BLAKE2b-256 0d17dc368cbe6a31f0a0029c4aa59d76b7a13ce39f45d1cd53a83f2eb5f6434e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 b0e88b485e5972cf0abeea565389908bfa2ca34fac7d1d538cd61283bdbe4269
MD5 d1d809a1f244513f4843f39ede7b85a3
BLAKE2b-256 d83a0d80ba8e73f62bb28efd4c644ee5e693f51bbe362ebb16e1cb58d4798da5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 ecdce1c7ba1ef6b7338e0ec48d23a11e036212301463647eb510f3a47f5f6d45
MD5 18aa2eaa11f293a231c00cbf0dd5c66e
BLAKE2b-256 9aba9b6d4d5d9fc3d98811d4ea05c9f733d926607f74cdf9e6529261c9eede99

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 298cb58a6241da9c583cca17184decb8fbf9941b7aa61ed70d91cd05b7b35493
MD5 19b2923aa451390b3ab20008bf380071
BLAKE2b-256 b3de0cff72ad4c711255ec53a52506e1ee8e3a57fd9fd1dc82ccbbe275f325e3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 a7f7e34f4b6fec875bfd00594215ff58aeb0785309e2d8da4cc776f3f55d3a5e
MD5 094e8ef7b2d9107a731346fe9b5ec237
BLAKE2b-256 7960ac7c3ffab67f21a013ffecb4ca8e4a81653afa0a65efd217b092cf20dc2d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 154ee4fc4bf7efc8728979cb0bfc9f1a282e1fd2d1ad3b143fb0589d3fd61e41
MD5 c1f375b0172b7fd0961f63d4691af18c
BLAKE2b-256 b9646304f87155ff2286d21dfa06201ecabd858a2841f6ba5a38dd9c1774801d

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp38-cp38-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 93da3585998ee5c4ed7d7f9018d0f680bb3ea3c33532927fe3fe6666ee5bd5d9
MD5 5eb65ca8f31b1177caddf4d8b3216741
BLAKE2b-256 2340073e2ea701f8d8cd1751701db9c476b9fac6ed1704d5da697c3511e7611f

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp38-cp38-macosx_10_11_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 6a797bd281f3dcf0415896667e80765bd9170a260b6f1f092d1096d77b369e11
MD5 a1721548fa6c7493f3d25bd2955571a7
BLAKE2b-256 287f681781005571cf00fe9eab426fe3a21992920dcb2526b926b8f3e1adb595

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 cc12160fd7a53c1cb7c8360434f26781f178bba25200132f6ce88ac0dc6a3e9e
MD5 00344566816ef47bde0e1abb577d0950
BLAKE2b-256 afb21732fb7d25aa36f305608b2b1407c63a8a4b3e2fdf903be616c775e624e9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.0-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 68.2 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 621c89d4a7f78688ea59c52a02b977137e6d5855f70dd29bbefd9e854e10c3d1
MD5 0a26ae0c5d234920eabd6ce5bc81679a
BLAKE2b-256 a77c50fbb920f1a0141a7fb498c4d8e7e19bca085690f2e9b39833e676e37d6e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4ac74281f479186d5f39fe619d2e6fdc7b44471e7afa32d7b27ecfe366f3a6fa
MD5 5484d0c85c0d5af73e18e6a507309c89
BLAKE2b-256 9fc3e5d9928b4484db6e5d49031a1fad6be453231dd7ee0c47613551f412abb0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 933726d202d923efabaeb42d5e9344a34969d1e587d9b99dc9db6d6f38055008
MD5 3d0d9b0784e77834a1d02e4e0683c4ee
BLAKE2b-256 a7ee3a8f17cbaba5ce1445cc266631dc1f464d43895dbdd8b616e57628c5cb91

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 cefef7d8bc71065f152d706b51c06702d36b6cff9ab7cc3f47c356bcb3bf44f7
MD5 b90e9073bf4c7b7ae9a5dee2a912ce6b
BLAKE2b-256 5721ed5251bd23c5da4bcdcce35025c3185c403bdbb7cd8993e504eabcf77da5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 2dca560d97467730f87b26a5ba2b1ddd24a3ba589d52593add55267c52b01002
MD5 66256582cb4f3f01bea02314f71212af
BLAKE2b-256 06c33cec60375cee537379b7b4ba669166bbdbdff14d7e4c159c6c6c8b1e62a5

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b4cb6d3cf18f5c2c2493219bc83d5db41cd54a872db9884e8b31c33bfda8116b
MD5 ecf2f8af3e57dc0a89150edf49c73143
BLAKE2b-256 7c9839d693d78a8a1a37edabb2936408b071c186e60c8850b6208fa4e74b9fc9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f505c090400139b0c64856b661b72b93d91d15b09b736c1a104c96581c31a08a
MD5 e37bc90743617a4a3f85cccac8ce9f8b
BLAKE2b-256 472951b0b4ebf48c36844d76b4b8eb9a4b02d9bc2eb591bfc72bd5149a2e4f18

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2583327f81921a7e01ad663bc20dad49fdd4286a5c3acea31cadae2074670bff
MD5 7297797db010dfa0365c24a76b55e104
BLAKE2b-256 f1cfc2ad69f6f125315ade024480ca93cf297b0f28a2cfd1868fc3f295336e5e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 ef03473b446b475fa23d03cce4a2d14f8206c3d4be1f8ba34f614600e79346f1
MD5 e72ef281ba7da556b71a211e1ffdd6c3
BLAKE2b-256 6c6640c47c4d9a38f15ebace4c1dd1e5a62d5b90768e27805013fa189c2063e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 0ab7018c19cd316c0d96fcf062879ce6d2dd75b41f3b120f82d7e5917becad7a
MD5 9d3c7aa94fb4337fc2860840cf73be4a
BLAKE2b-256 b8483cce728fe645478e4cfa7a3c20dc3bec7203346e0cac5d1740785f76b0e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4f8b44e86f3f545a8219d9b23db31e1422d15528eccfe20ab7a33f0ba2c48e07
MD5 3f94e2005a99f42ee2e90e92fd5fcb49
BLAKE2b-256 d567f780237c2727fb69ef90f0b361bc48f6439db5ebf7f511485a6c5b281ed4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b2c7cf808982f16ba9cd6f3e35ba5e9551e8ecf5e8b7ce1f88e0aba4d6cf2529
MD5 ce59b39fee8976e6125ba7576827e2a1
BLAKE2b-256 b678dfa9ac941f1a53f698d42dc6d80d8b1c2f5cf6a58169498aac11cf7ea287

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp37-cp37m-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 5422253d32c9dd531d3cd25f8d84fba59292b0b37e8add0aaa70297f7076fca4
MD5 5960a8e5209469bd5ff0d304e52f86a3
BLAKE2b-256 da18aab07113603e614a850fd38358f173def4e3b64a19cef40173f4c006c8f9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 0a5e507697102ab82f43e2ee6565b953aff52fb855edac34b9dd5781ca2ce1e8
MD5 47e18c2c73cbe58a95dcbb3c6119b461
BLAKE2b-256 75a20c6ecb6f3036774d916215f2a995f908893d2205969455756047c0d70623

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.0-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 68.2 kB
  • Tags: CPython 3.6m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 cbb4cca3429d31a13f0b96d59c891d3778a866f4dbb2f57e1691ad3f226fd27a
MD5 4d8b6e803d768b2d0786c56c144508a2
BLAKE2b-256 4501300d51aa34326b2d5b89383265a82918184c5ae19d899681e2d32adcb2ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9cdf3bb7b170c5db748198b596b9004d007a29511f00f8bade2a0460a5799ae9
MD5 62354e8341939606a52e0fead01bb17d
BLAKE2b-256 b39b8f7d055822d56c6a25bbe90179d577ac443096b6c115ab1731bd2769fbbf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 075de2dca3bb22e332db30b8ee5e042e3e2ec3696fa278aaf4a861356cd1f55c
MD5 bc5ea0887f4f75c8327e35e35714b6c9
BLAKE2b-256 254ca098731223f966901a2cf64a0b336e40d13f58f3f0ad81357bd63891845e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 78ce76445c570bf6f1d0b720dbb5bd350b900ae44a75e95a1bdc470a740fb2d6
MD5 fcb0802c42110fd58a41b52843e0aa98
BLAKE2b-256 2365a0230411feed528ac1e18c0f7caadc7f4b35266be47abd1e5cfdcb7df22e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c33340918a71fae5b810e140fe15b705c36f10e01828be92b51a7b0a519544b9
MD5 c0af3a20fd1c1c5e95154c7aeca62b45
BLAKE2b-256 16dd41da1c9fcff48be281203dacb3ced1f38be96d37c4666865c8e3e6f6b4cd

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 7ae511b31db485323d38b8b3eeb987f8e1508935a042c43e2243b9db3ff6ead3
MD5 5d9582856faaba8804179c08403fe0f7
BLAKE2b-256 ec41ea3374c403ae70b7e556401c8eb1eb18534cfb34f770eff1004766c5f117

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a8d0b395ba716e068fa74bc28c41e215dc0993010e838c89076ee2808efa0af8
MD5 fdcb769c07607c2d73bd958d8629be5b
BLAKE2b-256 b2425f075c9d64acfb277d70e3271ef83c0f3acd591ffe83790a5e6463fe7f76

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3f6b90061d983bbc45e1251ca784b00810ef29b494d461e2cca9d0764d4abe38
MD5 40f351a0ad68f7bc24dc165741596934
BLAKE2b-256 b5d63e91e9f4b5565087a536bcb17886bfee7708c4bc75bef2d669efc55b7529

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 6f6ae5a1e9dcb1ad576c06c6dd40cb74ec36f4a21682fd8924275ff9c880d0bf
MD5 a7bbef74c3ba2717a3d24a4477ffcba3
BLAKE2b-256 a571eeb011fb00b03a9dcdaf0bedd0df7403328b42ebb06322d943aec1f16948

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 2550a39864718010d8e5e811b93dcb9c70a17192d5dc3292644da503cce1fd6c
MD5 d77cf55e5d13dbf62f4d240f8ee5ffc6
BLAKE2b-256 5b33ca59cc68daa886b53a1d58519478836259219c573a6d94156d30f352f969

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 eed0a676bb3c446cc9f7f9860140075e77f20be71c13b1f2b2062d2464731b47
MD5 fc47be5c5cc1afc6d2816e70dbd6bed2
BLAKE2b-256 92f673c569a85f9eb8c3e6f42bc5b01f0fa9ebd66b7ff51e9a63e07a8845bcef

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7435847d6b9872e92c735b723f34da312cf457e8c6ac24311793b37a1a55545e
MD5 a4a080ca6f85980378577916d00b89a8
BLAKE2b-256 8bc766430cfb90d5c70dee1ac2803556ece972d2ca02a95faf5ad3fded755930

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.0-cp36-cp36m-macosx_10_11_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.0-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 25460a295b38da65aef5669a469ed7c18291f7c088177f6b580fc612452014a5
MD5 c62ee9b69bca165d551d053527bae420
BLAKE2b-256 68a5993149e30f5a203290eeb259d0411f88546bdb302e88e5dd0d0afe2e828c

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