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_bytes = Str(b'some-array') # no copies, just a view
text_from_file = Str(File('some-file.txt')) # memory-mapped file

import numpy as np
alphabet_array = np.arange(ord("a"), ord("z"), dtype=np.uint8)
text_from_array = Str(memoryview(alphabet_array))

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

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.10.2-cp312-cp312-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.10.2-cp312-cp312-win32.whl (68.2 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_x86_64.whl (289.4 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_s390x.whl (204.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_ppc64le.whl (227.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_i686.whl (210.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_armv7l.whl (198.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp312-cp312-musllinux_1_2_aarch64.whl (222.9 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (295.2 kB view details)

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

stringzilla-3.10.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (202.6 kB view details)

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

stringzilla-3.10.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (230.7 kB view details)

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

stringzilla-3.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (227.4 kB view details)

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

stringzilla-3.10.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (209.2 kB view details)

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

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

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.10.2-cp312-cp312-macosx_10_13_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

stringzilla-3.10.2-cp312-cp312-macosx_10_13_universal2.whl (121.1 kB view details)

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

stringzilla-3.10.2-cp311-cp311-win_arm64.whl (67.0 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.10.2-cp311-cp311-win_amd64.whl (78.8 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.10.2-cp311-cp311-win32.whl (68.1 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_x86_64.whl (289.0 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_s390x.whl (204.2 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_ppc64le.whl (228.2 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_i686.whl (210.8 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_armv7l.whl (197.4 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp311-cp311-musllinux_1_2_aarch64.whl (223.1 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (294.6 kB view details)

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

stringzilla-3.10.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (202.7 kB view details)

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

stringzilla-3.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (231.2 kB view details)

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

stringzilla-3.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (227.7 kB view details)

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

stringzilla-3.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (209.1 kB view details)

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

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.10.2-cp311-cp311-macosx_10_11_x86_64.whl (78.7 kB view details)

Uploaded CPython 3.11 macOS 10.11+ x86-64

stringzilla-3.10.2-cp311-cp311-macosx_10_11_universal2.whl (120.9 kB view details)

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

stringzilla-3.10.2-cp310-cp310-win_arm64.whl (67.0 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.10.2-cp310-cp310-win_amd64.whl (78.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_x86_64.whl (285.7 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_s390x.whl (201.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_ppc64le.whl (225.2 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_i686.whl (207.5 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_armv7l.whl (194.3 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp310-cp310-musllinux_1_2_aarch64.whl (219.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (291.1 kB view details)

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

stringzilla-3.10.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (199.9 kB view details)

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

stringzilla-3.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (228.0 kB view details)

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

stringzilla-3.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (224.9 kB view details)

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

stringzilla-3.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (205.9 kB view details)

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

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

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.10.2-cp310-cp310-macosx_10_11_x86_64.whl (78.7 kB view details)

Uploaded CPython 3.10 macOS 10.11+ x86-64

stringzilla-3.10.2-cp310-cp310-macosx_10_11_universal2.whl (120.9 kB view details)

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

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

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.10.2-cp39-cp39-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.10.2-cp39-cp39-win32.whl (68.1 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_x86_64.whl (284.5 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_s390x.whl (199.8 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_ppc64le.whl (224.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_i686.whl (206.3 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_armv7l.whl (193.4 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp39-cp39-musllinux_1_2_aarch64.whl (219.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (289.6 kB view details)

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

stringzilla-3.10.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (198.6 kB view details)

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

stringzilla-3.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (226.7 kB view details)

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

stringzilla-3.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (223.7 kB view details)

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

stringzilla-3.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (204.4 kB view details)

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

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

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.10.2-cp39-cp39-macosx_10_11_x86_64.whl (78.7 kB view details)

Uploaded CPython 3.9 macOS 10.11+ x86-64

stringzilla-3.10.2-cp39-cp39-macosx_10_11_universal2.whl (120.8 kB view details)

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

stringzilla-3.10.2-cp38-cp38-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.10.2-cp38-cp38-win32.whl (68.1 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_x86_64.whl (283.3 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_s390x.whl (198.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_ppc64le.whl (222.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_i686.whl (205.1 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_armv7l.whl (192.3 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp38-cp38-musllinux_1_2_aarch64.whl (217.7 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (288.4 kB view details)

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

stringzilla-3.10.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (197.3 kB view details)

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

stringzilla-3.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (225.6 kB view details)

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

stringzilla-3.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (222.3 kB view details)

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

stringzilla-3.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (203.0 kB view details)

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

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

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.10.2-cp38-cp38-macosx_10_11_x86_64.whl (78.7 kB view details)

Uploaded CPython 3.8 macOS 10.11+ x86-64

stringzilla-3.10.2-cp38-cp38-macosx_10_11_universal2.whl (120.8 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.10.2-cp37-cp37m-win32.whl (68.1 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_x86_64.whl (281.8 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_s390x.whl (197.1 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_ppc64le.whl (220.9 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_i686.whl (203.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_armv7l.whl (190.0 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_aarch64.whl (215.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (286.8 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (195.6 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (223.9 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (220.1 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (201.2 kB view details)

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

stringzilla-3.10.2-cp37-cp37m-macosx_10_11_x86_64.whl (78.6 kB view details)

Uploaded CPython 3.7m macOS 10.11+ x86-64

stringzilla-3.10.2-cp36-cp36m-win_amd64.whl (78.8 kB view details)

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.10.2-cp36-cp36m-win32.whl (68.1 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_x86_64.whl (281.0 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_s390x.whl (196.8 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_ppc64le.whl (220.4 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_i686.whl (202.8 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_armv7l.whl (189.6 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_aarch64.whl (214.8 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (286.0 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (194.7 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (223.4 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (219.2 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (200.7 kB view details)

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

stringzilla-3.10.2-cp36-cp36m-macosx_10_11_x86_64.whl (78.3 kB view details)

Uploaded CPython 3.6m macOS 10.11+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 d8bb26efe672de7be049e8a7d8463eaeb31e4b31844d192f3efdbfe31dda54f3
MD5 74a89fe408459dce16eeb8bb71d43d41
BLAKE2b-256 12efd14ddad2e5da2191b9d23e17c323b715bd6fcbbcbd9ce5384bdb2f0e7f21

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 369b1ed4a5744ce276621dd8ed6450be30dc5dc9d07a9b26ae4715272624b81e
MD5 77597db83cabb20e75255e9d2aa41554
BLAKE2b-256 76c5cb8905cd9db2e1f1b5426b8edfc310d20bf2316c52b61ce2e56ccdea1e5c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 415fc4e59b6c4c893e977c11d240717d7801d3475268ac816a84d4b828d42095
MD5 71ff9b6b2265db97c7bb0deda50fcae8
BLAKE2b-256 e0567d9325be45d127bfc7778db2dfa1697da6c9e3d714825baf29441ae99687

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 631dc758746e278d126a8e80412cb9c2f9c35eeb28e4cf782f8ae5680bc6773a
MD5 59314a5eda02bcafdae2e68142630176
BLAKE2b-256 de7143493d641bb34653c5769b5e080d561e7b60a2afd38f88d96169f2682f36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 ffe3a97af474bd778ec4bb07d1277332ad811aff7c4bc9d3777cd2bda1bfaaef
MD5 6f0e607241b86530b294fe05ea6bcb80
BLAKE2b-256 9cbdc9b4e13122dd5b19d5ecf60a83c49d60f35a300ab4893156839f720301dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 226eccb5c843cff6067a336a3848941d19b0beeab5b15faec2fea9eb0c9acdaa
MD5 7e68268a827b4d78edd1f39282a62ca9
BLAKE2b-256 ebda70d5ceb624b5c11af1c9eb080c5ebbcf2a55aea0b98150d832b836837608

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 92be197a28bffae3db35bfc628396148ff99dac4e922654ca220a763d91b6c22
MD5 1fbdc2773874ab3f741496a2290a331e
BLAKE2b-256 58bb7d9516424350cb711d41a042fe969d3ddb780235075719c221a5e2ffc2fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 1870c16b22e06a627076829bb25e10f8d32839115cebd718243242c5b3ac7350
MD5 d1ce677402e92d29303ec9809133714a
BLAKE2b-256 b39bc6980710a9393ffa6b8c324bef993420772f3db9aace85ce018f25e7036a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 af54b8101dca5aa54c5e001a509b243af64f9ecd68ab551641f64005da457113
MD5 5818999351f1bef35b548b81fc2ed1b7
BLAKE2b-256 ae194f55485a7bbd1270f8658dd1ab4ef3ef88c5767bcfbc1d5a8ebed7d35b75

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 31a26ac92be3be68bbcbbf5770dbf9c9981b37c037ee6e77343a708e13988dfb
MD5 226607514e7deb7d61434f470a7bfa3d
BLAKE2b-256 b251b241852a058e3d0e578240a1672a493e137bbdac16f13329d0edc4c9ef21

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 4966e88fa3305a422b41c80af9e8f5cfb04814e685a92bc977c676ddaaa44021
MD5 b9e00312f15a1ef00c9bc6eda6704345
BLAKE2b-256 901c1e16664132968a363b6bf99fd19e5486aca37df47612f77c68d3356c8eb4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fb25b7b4afb8c00c51ac0be6084999d4ac9ee9377d3829580c8c7d960fff7e84
MD5 f181fdf2288b5be7fb2d55fbf7227417
BLAKE2b-256 7cb25ee4d5af2b24c897ab8812fd7bc7cbe5db0a36662d76858091d0b8cd040b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9a328b037c462e17315c526538f1d21548d5d5ead153d98c3c6c1fab57c42cb4
MD5 a25b501cc8c1a55ddb4beb478cc1f251
BLAKE2b-256 1c479906f66b00c9c049ecf49b92b3304822cf7d84f80c226b66fc6480c2f6e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 79a94559fb25a4e8ce62b2caf9b4903d05de4c99b365a8b9b06eaae9b619f186
MD5 477e389ed1eff80c2acfa6a845e13acf
BLAKE2b-256 bf96d574405fd6d561c1b1ae3b02eb308d2d9c3ff7183f51e77a35eb1e817346

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f55479a08c3c94e2669dae9ace8dd8a592b3618703cd6f9c11ad978d13f2c4d1
MD5 f415cd54dcbc35eb668d60ddc5e4ead1
BLAKE2b-256 5aac749cb40b9f9c734c4e3d64714d7f3f3615d269d20d2fc6df7aa07bc5718a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 bb5fcb7c036e78521d10f00cbff0858089e9e9f36b47f839591c2d1e933d6ff0
MD5 ed7c8ef97ba7c0b8a64a95d89abdfbe8
BLAKE2b-256 dc6f7b940f0c8ff7204d481bf0ec26c04b86cc86022c3cc71a119be0fb40270a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 2bffaa806ac38f524aa1737b31a3f57bb3015739a3cea4542ff40e22aa6de215
MD5 60bbfc232f100ce9e6e614a24c5ed590
BLAKE2b-256 00b665377e29de2868344604ba4c12f7934f013b9d88e32aaaf9b68cf7235278

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 68db4a6a1ee8c0c0514496acce46516759be57b1421d0abc13a602ef2faee7c9
MD5 2c1f8a98fb01fffc214d869617fa7d5a
BLAKE2b-256 cd880d4c82c7c6ae34c63e0198da1afa69133e6493511dda6acc9605b1d35673

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c99de4f3fb0a1d7e97e00f7f66f5fcbcd6b638122799c87af6d8d692b8e7aa4b
MD5 9b196d6b390b6fcadf9ebe002aedbef6
BLAKE2b-256 a5c9f9bb85b04f0ca2440b124bfc8f703d8f909ba0c98cc48881bda75f98d8ce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 fbb1d50e8f25dd0ad6038049740986e789a9f2a799a50de89f2b69c7ad87b807
MD5 d30db1ebd9b63d85e48e93d1926081d8
BLAKE2b-256 6c3b4b5136cacfb7c5ca7a8ec19ce530b84552dab7d286dae2a3c79b2f5b0a65

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2a9ec90bcc542f3f8de915348ea37931c346a364aa8facfddd30513ab55b7ebd
MD5 9232fe4339a613d59cf6d46389ff7d8b
BLAKE2b-256 e4e3cc2daa7a4001f7b341708a2da6aa6bdb31769b3c5bcb1918fd2bc08e66db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 ecdf8be5fd32d192332b91900de8c45a5d1e5044373714a0fc5bd29db49d6870
MD5 c8f1d1dfa6d0d85634325b5390937800
BLAKE2b-256 2b74a7ca16c474dcdb1ebb3ce50af1f8111062032ed4bb6c3ee972a6be4ec386

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 6f81a1d69ad153ec6cf8ea221e1669fbfb41955a4943872296d6751557b5389d
MD5 1fa31ba41cc5c0055835bfa89c028f2f
BLAKE2b-256 7130b4b4b4a304d47b144642315a5cfb8044e278881aa1ce873698e15c4f281c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 2ecafaa25c87333cb604dad2d81f47989fffdf0a5c5acffe3cc2ddbbb1932a4f
MD5 0100ff781cd966413fb8ce9584a57f3d
BLAKE2b-256 9f2c3e391673d49752f26d4db6fa4557baf6f96f728ccce04f0d5f1f6bd1c427

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 9b8a3731b525b689e11e8c8ef3159587ad33b8045ccfa2ac54fb26c64244561e
MD5 fae590a1c5fb5598994e070e390fff9e
BLAKE2b-256 3c01f72326fc75db7f0dc95676e05844af3f1c82df88b11d9d0579dc9996018a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 581920beee9f4032a15878fb380f0c3c21cd735eac49e6927842b9f6d7f89bea
MD5 c095bf5fe9501cb3c8e54e9e0f35e943
BLAKE2b-256 ef665d85f0dcb73bc151d18af66ca1c192fc53314fc8944ec68c1624452e84a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6765bcb8b6a70b10824181af49cd43e27c1f9787a4806d451fc0603eeec3307d
MD5 cdf1f7079707301139db675811047fc1
BLAKE2b-256 3073566a5747efef34c5b72b03072a26e05480492e07d99d0c703bb0789aa95d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 ce9189d61d801de7c5be4c454f65e9845abe43daa2a7c9660fd95d967e0f7d39
MD5 157a4d52204104946f5aa7c490e61063
BLAKE2b-256 cf7c696f8c6dcfe9cb218194c1f1fa6671ff2757d39145d376981061c68e45a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1764f07814f6966a8d49dd9e7c299fb8f22a117de8573ca06ed2054f614c2e60
MD5 fc4e05b96f8fcb573ff9a9386cf2703a
BLAKE2b-256 bbd1b8e172ac4d34763694d0cf2558de781da73cebc487a920179151305bfe4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7460505fd1c4a26e91a9b42df5e28a2d9f01819b5315622af99922a39ac0be93
MD5 ba42207e4f84b11c22d27c2691e7bb2e
BLAKE2b-256 e73aeee3f33c218894ca24fadf5b80a12e317db21e5d72a267159c042ef65835

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 41577ce6a28f70fa5917521ca106b1f51632ebb067dff105bd8d8ec1981baacd
MD5 c6e5cd16d5077ca6a835af0dbb9d9fcb
BLAKE2b-256 2851236f7d578161aabc753106ae8e143c63d45118d4ae2c24eecad70902deea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 68d8517b24e0dfbf412282c36a453bbd0cf19861f8183ace093b11c39c8c7662
MD5 a89e2b23898784178ca57276671c66dc
BLAKE2b-256 913cbb7348475589922dd606b9c92ab817814c2eb59f364e2957f2050ad6d95c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 3b1d96f3734815fee8bc0f0ff278c8bb778e2f7c59fa51997345cebdda155154
MD5 63ebd1990a75f02d6074a723bf0c732f
BLAKE2b-256 a487fc839b8b95b9f05ec8e2697ed47b1ffb0ea85e29c952f13d2e883dbd2eb4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 2c5045da82871855dda2a0acef56f52e4e6303642f9dec0ecf97a77b47a18c98
MD5 a4f1dae33cc10665308ec91b67d75704
BLAKE2b-256 638f4a48a47c30dd0b2e255bb05c9056a918ce38b5463d6363ade892ea57b777

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 92a6c3234329cf1f8a2e4d33176b4d7a5b3328c0fcc169db40e01dde5248644e
MD5 99c107b6efaccb41f06834c645f4572b
BLAKE2b-256 f023793510a6d54e1c07f1fe41d9577166fdf47a3ee73338024a685725ec2f2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 defec536f732545d36e25a54c006cd96f1b4732ef42288b8a127221cd7a870c2
MD5 6d899620c90be903a35542081d8dcc65
BLAKE2b-256 83e152fb6d03a656e359e5a3d65ca90a7c1222c860067c89b383e0dd655ab35c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 44622b47a4dbb226f98a17fe32926d69cf1e17de6ff3b38f863d10ce3ca23576
MD5 d3408ec465795580178b931fe42e6651
BLAKE2b-256 2fbf802cbee5a6f545ec6ed5f360170a008a06893a4db63f55fd002466a1e35c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 947ede679956b060fba84f726b8c5b2d5d18a15168dabd2c532e1d139e37dfa9
MD5 6b5e6053f2816aa4559169822deb0922
BLAKE2b-256 00202e9633dafff44f06e015b78993a72eedf73e46fc6c575dacf9de899f9f07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b77e79e4600258b25590fb5d28a03f86067540121b900547f8390e5528523aad
MD5 4fb8882a8484e7b5df77f9af1dad750e
BLAKE2b-256 6bbf053ef26875e638edf39c2f274b3b13598cc9cab0001156d48bb613cd1097

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 f3c51a072896c75d979413208e3099f85a29d431f3cadf8c3af1d2c09512c8e0
MD5 bb93935a09094f33b7cd74785e483f32
BLAKE2b-256 fe40b3acc83edc1c4351258cca4e6c2c340e9af8dc2d66bc5da711c64a131d20

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 dde1ccaaa87b315a0b9ed2fe9078c4f0de5814cf24ab834329ee16760f802032
MD5 06f64c2c5c1b987e785945d00d500ec8
BLAKE2b-256 1993eba7d362df73a7677e47aa46c2b4fd30bd1a4a1c3a27c272d42ef6888fb1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b9d2228c060a13bc4fdbfa3d45cad861760acaf01547d3291c9d35a81843fd6f
MD5 e5e17195825df40955d8acb9fdd128a1
BLAKE2b-256 699c1b16c713686a00652626304be8310b8ff8a1445fe23bdb055c6c5fb7084e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 6bce1928abdbc322b24d2ef8a0ed3dcb0db2d7a856fdadfb330d0a46c483e7dd
MD5 d806c9ae1c9831511c71a51b3fde3056
BLAKE2b-256 8add1107eefe72a218575d3f3599d9d89f434698be3d61cba154f95cd71ee878

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ce8f3bf63cfcc5bcfeb23069f21b38057070a51949eeb64fea704f5200a7c81b
MD5 cf90f32f65914a010a0e97b56a801aa6
BLAKE2b-256 721a4386b9b99c00072af61556f06fda2185fb3bdafeccdf07cc0786077ef7cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 77f482e30d4663963b0a3fe6814047d3680ef2fba9f3ef08e09b18dbd1d2007a
MD5 c1be0921a734994ba56f84e0c04785ea
BLAKE2b-256 1a2e2bbb3547149ee53135c6eb55c936c184e49d059e9fb8ea9f39490f51a5a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 01b6e33a384b0e93645893a494631a2979cf441d8c6c6977f04517fd48ae485b
MD5 28ed59db652e04bd8b5a595ceaf4849e
BLAKE2b-256 2b9537e5776a848827b1619702bdc3552a29c49d4eb84f1de4c0e4aa33b42a20

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a9bd3db55ee1cb1bd7df3eb7b0f432a683b05fd2621928e83a4211c827304b1f
MD5 ce8dd1402cf47c4c106612705f39ff6e
BLAKE2b-256 bbd98b962febfc917e784df1cd30d81911ec9120f362167993c8cebc6802f50d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 900bd2b35280304d3ea4525c9f365cd2e590f544788aa3637e1512c244325989
MD5 9ba89a82c713bd615c97d92e0a6192de
BLAKE2b-256 2efe61d9b64d5e420e27cfdb665d6f23bf74cf13b60bd3e38ac2873084b40170

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a92696634204bdc941ae3962d6abd7d9b82ba4ebc8128a2a6ab161c1d9174fd5
MD5 2eaab033a4f88b8c46ae9f26ec59ed1c
BLAKE2b-256 145a49dbc3417c3a782e13dd1e3a3d3bbfa32cb181fa1742520b2a27dca301d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 3a7e57371d6c79c057a03e35354e06aafc9bf93507eca66730941fcdc2d42dc6
MD5 b93ba5645b3f18020acf5842cd2514ef
BLAKE2b-256 7e813df61559d8fc4df50a31524aa91af0bc1fa5442aa9eb046e4f06ca4fa2d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 8094db489379942cdf4a4836df32beebd9ebf06bf1d3aa1fd90dbbc472c142aa
MD5 7d196095ad767914e9bf0225c33655ad
BLAKE2b-256 e05a01536cf5b19382264837ff5956922913807d38c896f7f7cd9ad9cc88ad82

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 2edf148b9f93b6569c1a0878970d8c01e25a2c5a35acb6f9eb9277471499563c
MD5 e2a7dfd50e43951dffbee318285c875d
BLAKE2b-256 1852961a6959c883ee874be8394c3508690b2ad5cc46e58368d628c18f41718a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 99e588baf3cbca0e8a78720b5b8ef0c290ee25f08ba7ef8b0f0499084ec3c531
MD5 9578c11dc3b184c6155fb2efd4db3b0c
BLAKE2b-256 dd63124451c18f5ec3cac7ee83ca2931d1c55714c41eb5d5af1d9d33d3d4caf4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.2-cp39-cp39-win32.whl
  • Upload date:
  • Size: 68.1 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.2-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 c276527d66a608de1d1830f60b9dcc9f9f9123f33248cba45049396eb6c7c8a0
MD5 b198b996f4e72327116a2005a785b0ab
BLAKE2b-256 ca889a1c903c299780c73bd45cc0f62e433ab343484cbc0e8790166608f4656e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ffccf1bcdffd038a83b5486ad1cb763d66b41c933b8ff6bf0b4438b2eec9e85f
MD5 d6ebc59a7259d5ecb864489dcb2bcfa7
BLAKE2b-256 b93edde460742dd4d44df621ad9ed12c099637d4848cc7d8f76110434ed47fdd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a7fb3a4c53f1a67e22f3ceedc93fd2d35df83796011f2ac7a4e354b3da50ed81
MD5 72138725949b3872d23edd569bbd8843
BLAKE2b-256 0d4bc6e202656d6af3df7574504eb791a6674cea72ea1733efe07eb2878a3930

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 0f5811e84fbe4ee098a523a87be7c0e693fd38b89279c74ed3a0cb1c3e111d6c
MD5 caf8439ce7621efc213981f09ade76fb
BLAKE2b-256 2fafed5b7229169ded824c7e7c6489aeb4e4affbf0ea0ba5b3946fe2037ffa1c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 222fe06dee06d980c164bfba3f725682a47a351987ca01e68e2206d0b2d66db6
MD5 809d753c235cd2df712a593dfb34f046
BLAKE2b-256 f3cf1b8caada80257983d2f07e547b4a6340ab4866eb53f7d6a1a9a542fe08dd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 2a57f21e18e82d6cfd58e8c4199065dd3c96aaa0224d557770be19b567a9ec83
MD5 b56ab9c4318a324cadf160a9e242456a
BLAKE2b-256 dace3e08cd5a682b95d64f176a561f9d624405574ceed010f4d6cafbce2ca589

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 22a111875b0b184ad4d70c808d1b2d5fb6e37c59be42b18141e4a522196b852e
MD5 cb12fd757078201c63ce3b021b75e8bd
BLAKE2b-256 ffdee4994dc9ca3babe415740653c0e65e519822fca73ec2ef384bd4b23a96ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b08d53907b7467a2b670bcc15bc128760b2b1cf9d02524f303054d28148d6fed
MD5 ed288c38a42bb06ed3b9c5725abab340
BLAKE2b-256 c7bfabe3e5ce271f2fca14adf61181d871133e847ce3b905993038161ce96185

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 71cac0b453cf1c133f37b16ee852d40f49adb1b34ad59b5180df0aba9866e3c3
MD5 8237e891208f672b365c67459d89ab80
BLAKE2b-256 79398022db9229f57ba12368dbd3a981ac57eefd01437ea68e74688cbdea3fda

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 535974c4f3853fda5af7ab27924f95c1f743ff9b09f1e9f9f05d2368bd5cb1d6
MD5 4a07d87290d74c481c651a205fd2cb6c
BLAKE2b-256 2c4a2a4e8696bb7d031d1067d054a4da90ebefa0162b5911ed6c5a155d35f2c7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 6d9508799b3c5c630303b13efb788691d548f5ae301b5928f93de3583a0819a3
MD5 0e64f29c557161c3f9ffec02c5c8901b
BLAKE2b-256 19fa17ce17191865d1afc64de1587cbe286b6012f22b496a8bceca0de927d84e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 cbfec67c993d3380f5836ee74d838f199a806cb45570ca9e7ff2f14f5041be5f
MD5 be1f3dc9cdc97b15264832a28e7531ff
BLAKE2b-256 7c29f4c1390a71346595f4f6ff9cc058df3529042bfa4d339cfeed0c33889c94

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 23967fa9a7840f07384f8d3fc4ec24bd8dedbef8d5580d48606ffbf160a6aa8d
MD5 6034845534d695f5d702dec4d47d3591
BLAKE2b-256 edb3e4588f10d45410252c66626451b33095c271c9e2ef83c12b0b4e4d7073cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 778a17da3f8376db6b15f9c8d92acafc5d620265dad532c479342aaadf69e127
MD5 65dd69b3165771d15b238ae9b86acee2
BLAKE2b-256 b898d3c482e172367eb7fe84f6b652ca87987100dd9869609781dbfff182f7e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 dcb111f0789c496fa02710cd7102d11c41e75c7afece61fbe5a5ac8a01a41dad
MD5 d9f8a192d6e4f825a68eed21f0d8a870
BLAKE2b-256 6a2099744006851d6b912de0d35f50bebbfc22305779e13c5971120917d92064

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 13842e21155c19997465b5136128581dc9cdd35a5cd8cb7cf30eee75da61467b
MD5 7c40e392c3cec3315c352ce3607db62e
BLAKE2b-256 cc33b68b6cee8a051707cf5a909ae28cd840a281ea85d3f3fcc32037ad51ef07

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.2-cp38-cp38-win32.whl
  • Upload date:
  • Size: 68.1 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.2-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 393985945ee710cedca1c50db4992f4c3385ee4235a0cca45e63a6a48d1a4ad6
MD5 bb2943a863373997483ae9cd6a703298
BLAKE2b-256 12ad9a8ce07562a8881f779a02808d74733dfa0c30422c43916bffd797936889

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 10ee740ff2e7f6a43017f967ee8cab7db3b18e2f6e3a77bc3cf440a09873e7be
MD5 041250a70787e7a6b0e13acfb79b02c5
BLAKE2b-256 ee2d0afaeb34478a67751d43abea98648eaed95cda584ab6926e98b33808771d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 46b9186c12ea4bba949a8dacdb1820ca91a5daeb1267d140859e428d33428698
MD5 543df3cdd76eaa68dae8f79b62186ed8
BLAKE2b-256 cab6892fc5a126531fc90c603b28d39e919bed10a5ce8865ec17bb156629ce19

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 3a049a4403bfd01f65df465a0cad7f872e8a09e756c199f55ad9876594ce5b24
MD5 08f08493d8ab9150837c95c6cd9fa977
BLAKE2b-256 8201dd44b506bc3657544cf33f9b79dea978765000666d135e60f012f59bb606

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 648179fce928d3fd1b0c2fd472f9f326b4c6c4c286213d3dfa30a9e502886271
MD5 16b3b33117a41767d252b33deb7a2222
BLAKE2b-256 bf1472cf3aec83426df726498caf70ef9341a250ecca2ac401837eb2f7574039

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 f3041b4b69480fa84661cfb25462ac345e53e5fdef5b8331757800e4931889b1
MD5 af0285346366d2396b15eb974cd8ebce
BLAKE2b-256 4d44762b5930a287261b3a2d1f9dd8570c10bda7c0b79df3c10e7fa518e391bb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 10523780f94bb73e3ceef08d7adc5a26576676657a2027109070444992bbd000
MD5 c9b0ee51bd600e14c93408efbece694e
BLAKE2b-256 66fec8327fcff97c1c30b833d99a2d4b810a7d6629754749aaad29b30a1f7168

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e0b92f6b14b28dc9772341f3f07edd842d140daf06f93ccb94f5cc7cb6cc08f5
MD5 49237bf8d3461bc2a05ce9c98bbeac3e
BLAKE2b-256 59a4550eceae1a2da177e32b8892f5d13fd341bb6170c23fca994d166c1764c3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 0b301d891d83533e3f603eaf8f962b2f8dfce8781fa041efb1c4a0edeeeb6728
MD5 926238415a9d12e78926d5cee4858c16
BLAKE2b-256 a8aa0f7145bd5b8ef4dbb318c69f9ea8490fc08d315932e0948ac5ac8b2ed2c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fde2b376b77c99dacf6c1604d6ca45ffc88b6fd6712f5c10db6be2402ed4ad63
MD5 1590f737c5753d70b77bf2fa6d1cc8f5
BLAKE2b-256 3c8bf105285ad947401cd1fe68a22b3e36474563aefd9866a8cf1137421f3769

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0b4617a8d1e82a513ce181e8afe07426aadc3d9b7152fcb176f8f0f5552ba005
MD5 f8a4ece12e83d173a5238d01a2e6394b
BLAKE2b-256 e3d3a4948c651f9a7b353a5048f98b75ca434f426ddee908ee1408bda7baef46

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 cf9fc536134bb13bacc103674d5aac2c9e0b75fc584790bb9bb9f9ac9f701366
MD5 4707849705df85473d83a01f8655dd12
BLAKE2b-256 d274f717e7c6dcf0e1624cddc24cdb5aeac20b5d706d96c28ea17ef12178b6c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0ce142ea4ae06ef6b9fb80eff33c0521d628f7a19828b7a5579874c86919f504
MD5 27dc207f8b8253b0d15ab2a6dd1cdaf5
BLAKE2b-256 da3652fa6d42b314b02b2bf817b28dd1d71e557eababf382090377fe82fb441d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 a4fe22ec1e0ece2205915a8be392106ee437d5dca44fa173d135486a3d21e558
MD5 3e9ff7b594f98abd3304afc59ab48240
BLAKE2b-256 c61f8d1add7dd10e43f411d8855495171c3a02cef571efd61f56f23b98e9cfb8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 478326b88b8d477313da05611bccabc1a5629fb452e0392981071256e80ca8fd
MD5 e192937bebf78be7ab43797268b3552f
BLAKE2b-256 95efbfde1ac633bf5a821ae06b78f6dbe08a155d6564e9fcdf05f6593ee2767e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 9dcddedb9814b72164ca9a09baed4250dac666ae02f384c338eaf8e8343b5f31
MD5 4325996b1d2f1e5d760812bb7ea81017
BLAKE2b-256 715ace6713d5bd7ac63e39fe42b533d3683e67c1033e169c26e27ec51b8e908f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.2-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 68.1 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.2-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 32f89e576e82886c82e37bfe2c2d33999d7c8875d1cc1a45f3be8b65a81b0a75
MD5 bc5ab235fbde19845e1bc78731e6c921
BLAKE2b-256 4cdd1219e49cdcf152e0435f70cf017d81250705fd792e391e92f5b2970272b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 500454af6fb40eb259cb0db7378c0c35eceb3eb0912813c6e1b7567fee9c37ac
MD5 2a30811cc64933417debffbfeaa49014
BLAKE2b-256 0eb0ce0140a0e23dff705cb8dae8ab5c0e26e49350609e1d11a755fc0eaa47e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 6c514af0f2a3f912bcecd524f1a31950118224d9d718e71872e6b4c63cf14033
MD5 d3c1d741ff8d173fc548db127123e5f3
BLAKE2b-256 21c32ca0ce35fc54bf31ae41117f1fad700c1ba9adacebdaa00f2531a18bab03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 afe500c52749c798c490f44d9bb957ee36a6f9947946ef3531af964369d85e8b
MD5 0e37306a6475593fe67f9abd0e813fa7
BLAKE2b-256 07dda8fb40a1612bbcace3b0b46aa3c8cda5e0e0753342788586a0a7fb2e3318

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 a193618f93b60072813e7bf494efdb77cac4f199de321b1971927901ebaceb59
MD5 28ab89372ca05827b22ff960e4fd9bb7
BLAKE2b-256 b1571cde5b22f38b56eb977a5fb827f13617b2e0498096fd551ba5c052b925a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 cf9a73421d6e2b7dcf4ae06a21c1910e22c85e063db54171cc990e67c219988c
MD5 f57a307120699b734d6cd8dfafd5b0e6
BLAKE2b-256 6d1b7cf59822ada76d47943fa24914d859488856d2cd1dde0b82efd6da3b63fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 506b8d0653947a70eb7592356ad9ad26efa146fad36ab1160b1ed83fb66a3cbb
MD5 a7a7eb5daea42e6e179f85d7da458be2
BLAKE2b-256 6d187877e5265b0f2b6251d3c241b4530938ed9cf9a12870313300ccdac016ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5edefff2635c69fab3b2c7791c8e0a058605b9eb7393d39932dbc885e5c40029
MD5 98a4c74f35c46611dfcc27169813e457
BLAKE2b-256 15d680135377ecad89099cafddfb8366de67103df018eaa8f16ca028322a6e41

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 393f41ed6be44ec8b919abd4f943bf899ee55eadfcd7ac7e294ad047e456f54a
MD5 065a11fa1a4fa66c40937da458d6ebe2
BLAKE2b-256 a714212d6d5329af92ec6d5fa1dc122acc0bb6188304f9f41a88274255b94976

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 e69958ebea434d40fd86f5798a5e1a34875b53ca2e75d7096430496771fff593
MD5 c17a921293d3cc541d9a0379a7e9ea13
BLAKE2b-256 69ba1f58ac8377a7ebe1b94720c37f188ebfae2ca836db3a2abedd149293fca2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 687bf471025f83d94dcb86a2359df1eff86d19ea6d0c908efc97fa52657c3d6d
MD5 c3f4c811bb002804196074ebe174ab70
BLAKE2b-256 6f7e70616e572314c52138c937b9557cef19e67e2efd965c1ff0ff5f7e132f7c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7b435c5495c9565bdbf701bfd7d989aa3047b443cd973397df5ea80df604a33c
MD5 2a5faed80353836f59e5e16e6e89c6e5
BLAKE2b-256 a07615892bdd386d63b6b4cd905e27da0148261577d329b20e88a2e818102018

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 0a515e1f0e99d4356dd2685098d887d66d709123c69ff44ff7b91d6fa729d8d3
MD5 d88145b3e6dccb955da83461f4f31a86
BLAKE2b-256 dd6c657703217fce08ff7dd8949991a2e376d4c52d26f1aa44a1d5991f2629d6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 bdca67eb071e3db561bd473eebf5431e505e58b055c2e7362174904e2232225d
MD5 da6ab907096e6c9961278f2fc021b5bf
BLAKE2b-256 fbdcd6a809387c099a720463d589369a856cc446f81640818fb2a03b36b44273

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.2-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 68.1 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.2-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 9c0854b3d1ab634e6d806eef8a391fa959e8d5b860f51f15efa40a71cb88934e
MD5 aa29e04b23a6e719cd0364f4334399b7
BLAKE2b-256 f70bdb3615758abb43d1d0845187c8879e4c4d177e5b64828f065b0814955090

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 40872ca0d5a88a561026b180380adc3b21e5540ab45cdfd3a7f74a05f6509650
MD5 789be12208d8dfb1d35614f9ef9a0d96
BLAKE2b-256 ba115a9bc16f8ebe9626bb45af08cf5c982cb7a102494c5a5e009d8f3be83dd0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 519e38034916790f5d6a6518ab05e58ef06a2da105a172f95661325ce38964ba
MD5 d4e8d52fd68444e6f175e3c253054602
BLAKE2b-256 78265b32c41b0075d02f21275e145d2a207c80e95ef11e094c26e0e9c5c8de7d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 263c438cf98d3d4d9e8e11226d62a3964a858bad37cde07a2d93de8f8c6e6ec3
MD5 6825db3d470a098169d6289e48a9ebf1
BLAKE2b-256 6a5152b8fbdd960f09c3c3b7406af3d3b06d136bf46e6920ae0470648200c6a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 cec1653032ecc59cff40db971564677a0888764d0c667fb8dc438c78f0db2bfa
MD5 e8a74ef521892e4ec9e89d6d9a561a25
BLAKE2b-256 bf21b61dcec76b79d3f6e3203fd64c2050c4f71958c77487cf33a354d4eeb04a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b25bf383323df456253ee68b5ca23e4e1857f10bc6fc0a9081aa5104414628b8
MD5 67497df079a5da8c076dab28b04c3267
BLAKE2b-256 061b749690dd4518349f0f88de2afac9c8cb3be1c8b60643ab19ef581eb33585

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 101c0cd447f8de375fe70e3aa7ab0f8fa186b10b52a4fef10141a2778b22f9c6
MD5 466f2f156b19a79a7da1e9f3d3a8afa6
BLAKE2b-256 804b725658a0adbdff12bb80167203aece6191e65f10bc94deb3f82fc6741dbd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ba1c4c13b9bf4a730375a0b7e9b8eda2f98efd386bea245b35c18356a73787fd
MD5 8e379dbaa696683a8264074177e66f26
BLAKE2b-256 46c329624424b88fcb66d9b25e55bed717292f17ec6fbd9075dbe5cc83fcbbf4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 2219d0bf19478333a2216f9798e29c90d908727718e98d29374213340fc68e77
MD5 0472b35c0607daa6e2c6308d3c8f8717
BLAKE2b-256 073071f2d738006889b02eb7c7afb3844db2b956c4aa85e20035aabedb9101cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fa8825026ad3b488ef1ed937824ce81ee1fdf7a8ff98215db75d93ff78b6fdb9
MD5 ecbb195db8f7acbc29f9f232865bff89
BLAKE2b-256 50c5f3fbe997885959b2ff169f72b1256dafa21d2f2a5d25670e525e60a6c89f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fdf56fc8a4cee5632910d441ba17fd93e6f3fa28c5898d652c4da993db2c61a1
MD5 47844a2ec71d11d5f4ea71fc00f71d75
BLAKE2b-256 65863214e56c8b46b6f854acfec51d6b2f4e2d0c72688c21ea83c477c36181a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 c48413e832b4accf31a09ab382f3fd08398735f399948820ad13153764fc9edf
MD5 69bd2f67c9d190cc23fbe8ad8d2d85d4
BLAKE2b-256 246d7a8920d26cbbd9ada61295f113cad86af01f1285765c15349ea01cda1a92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.2-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 48a25e52539b2c55f726604b1c6b1cbb8fe85d68bb08b89d8235746732b0b18e
MD5 e32c2a6c187b5162e33bed96c422d535
BLAKE2b-256 f23ef9a12edce2a66d685c431545364e33e3a3fcab541876ec3e6ada36a6b632

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