Skip to main content

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

Project description

StringZilla 🦖

StringZilla banner

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

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

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

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

Who is this for?

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

Performance

C C++ Python StringZilla
find the first occurrence of a random word from text, ≅ 5 bytes long
strstr 1
x86: 7.4 · arm: 2.0 GB/s
.find
x86: 2.9 · arm: 1.6 GB/s
.find
x86: 1.1 · arm: 0.6 GB/s
sz_find
x86: 10.6 · arm: 7.1 GB/s
find the last occurrence of a random word from text, ≅ 5 bytes long
.rfind
x86: 0.5 · arm: 0.4 GB/s
.rfind
x86: 0.9 · arm: 0.5 GB/s
sz_rfind
x86: 10.8 · arm: 6.7 GB/s
split lines separated by \n or \r 2
strcspn 1
x86: 5.42 · arm: 2.19 GB/s
.find_first_of
x86: 0.59 · arm: 0.46 GB/s
re.finditer
x86: 0.06 · arm: 0.02 GB/s
sz_find_charset
x86: 4.08 · arm: 3.22 GB/s
find the last occurrence of any of 6 whitespaces 2
.find_last_of
x86: 0.25 · arm: 0.25 GB/s
sz_rfind_charset
x86: 0.43 · arm: 0.23 GB/s
Random string from a given alphabet, 20 bytes long 5
rand() % n
x86: 18.0 · arm: 9.4 MB/s
uniform_int_distribution
x86: 47.2 · arm: 20.4 MB/s
join(random.choices(...))
x86: 13.3 · arm: 5.9 MB/s
sz_generate
x86: 56.2 · arm: 25.8 MB/s
Mapping Characters with Look-Up Table Transforms
transform
x86: 3.81 · arm: 2.65 GB/s
str.translate
x86: 260.0 · arm: 140.0 MB/s
sz_look_up_transform
x86: 21.2 · arm: 8.5 GB/s
Get sorted order, ≅ 8 million English words 6
qsort_r
x86: 3.55 · arm: 5.77 s
std::sort
x86: 2.79 · arm: 4.02 s
numpy.argsort
x86: 7.58 · arm: 13.00 s
sz_sort
x86: 1.91 · arm: 2.37 s
Levenshtein edit distance, ≅ 5 bytes long
via jellyfish 3
x86: 1,550 · arm: 2,220 ns
sz_edit_distance
x86: 99 · arm: 180 ns
Needleman-Wunsch alignment scores, ≅ 10 K aminoacids long
via biopython 4
x86: 257 · arm: 367 ms
sz_alignment_score
x86: 73 · arm: 177 ms

StringZilla has a lot of functionality, most of which is covered by benchmarks across C, C++, Python and other languages. You can find those in the ./scripts directory, with usage notes listed in the CONTRIBUTING.md file. Notably, if the CPU supports misaligned loads, even the 64-bit SWAR backends are faster than either standard library.

Most benchmarks were conducted on a 1 GB English text corpus, with an average word length of 6 characters. The code was compiled with GCC 12, using glibc v2.35. The benchmarks performed on Arm-based Graviton3 AWS c7g instances and r7iz Intel Sapphire Rapids. Most modern Arm-based 64-bit CPUs will have similar relative speedups. Variance withing x86 CPUs will be larger. 1 Unlike other libraries, LibC requires strings to be NULL-terminated. 2 Six whitespaces in the ASCII set are: \t\n\v\f\r. Python's and other standard libraries have specialized functions for those. 3 Most Python libraries for strings are also implemented in C. 4 Unlike the rest of BioPython, the alignment score computation is implemented in C. 5 All modulo operations were conducted with uint8_t to allow compilers more optimization opportunities. The C++ STL and StringZilla benchmarks used a 64-bit Mersenne Twister as the generator. For C, C++, and StringZilla, an in-place update of the string was used. In Python every string had to be allocated as a new object, which makes it less fair. 6 Contrary to the popular opinion, Python's default sorted function works faster than the C and C++ standard libraries. That holds for large lists or tuples of strings, but fails as soon as you need more complex logic, like sorting dictionaries by a string key, or producing the "sorted order" permutation. The latter is very common in database engines and is most similar to numpy.argsort. Current StringZilla solution can be at least 4x faster without loss of generality.

Functionality

StringZilla is compatible with most modern CPUs, and provides a broad range of functionality.

  • works on both Little-Endian and Big-Endian architectures.
  • works on 32-bit and 64-bit hardware architectures.
  • compatible with ASCII and UTF-8 encoding.

Not all features are available across all bindings. Consider contributing, if you need a feature that's not yet implemented.

Maturity C 99 C++ 11 Python Swift Rust
Substring Search 🌳
Character Set Search 🌳
Edit Distances 🧐
Small String Class 🧐
Sorting & Sequence Operations 🚧
Lazy Ranges, Compressed Arrays 🧐
Hashes & Fingerprints 🚧

🌳 parts are used in production. 🧐 parts are in beta. 🚧 parts are under active development, and are likely to break in subsequent releases. ✅ are implemented. ⚪ are considered. ❌ are not intended.

Quick Start: Python 🐍

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

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

Basic Usage

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

from stringzilla import Str, File

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

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

Basic Operations

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

Advanced Operations

import sys

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

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

Character Set Operations

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

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

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

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

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

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

Collection-Level Operations

Once split into a Strs object, you can sort, shuffle, and reorganize the slices, with minimum memory footprint. If all the chunks are located in consecutive memory regions, the memory overhead can be as low as 4 bytes per chunk.

lines: Strs = text.split(separator='\n') # 4 bytes per line overhead for under 4 GB of text
batch: Strs = lines.sample(seed=42) # 10x faster than `random.choices`
lines.shuffle(seed=42) # or shuffle all lines in place and shard with slices
# WIP: lines.sort() # explodes to 16 bytes per line overhead for any length text
# WIP: sorted_order: tuple = lines.argsort() # similar to `numpy.argsort`

Working on RedPajama, addressing 20 Billion annotated english documents, one will need only 160 GB of RAM instead of Terabytes. Once loaded, the data will be memory-mapped, and can be reused between multiple Python processes without copies. And of course, you can use slices to navigate the dataset and shard it between multiple workers.

lines[::3] # every third line
lines[1::1] # every odd line
lines[:-100:-1] # last 100 lines in reverse order

Iterators and Memory Efficiency

Python's operations like split() and readlines() immediately materialize a list of copied parts. This can be very memory-inefficient for large datasets. StringZilla saves a lot of memory by viewing existing memory regions as substrings, but even more memory can be saved by using lazily evaluated iterators.

x: SplitIterator[Str] = text.split_iter(separator=' ', keepseparator=False)
x: SplitIterator[Str] = text.rsplit_iter(separator=' ', keepseparator=False)
x: SplitIterator[Str] = text.split_charset_iter(separator='chars', keepseparator=False)
x: SplitIterator[Str] = text.rsplit_charset_iter(separator='chars', keepseparator=False)

StringZilla can easily be 10x more memory efficient than native Python classes for tokenization. With lazy operations, it practically becomes free.

import stringzilla as sz
%load_ext memory_profiler

text = open("enwik9.txt", "r").read() # 1 GB, mean word length 7.73 bytes
%memit text.split() # increment: 8670.12 MiB (152 ms)
%memit sz.split(text) # increment: 530.75 MiB (25 ms)
%memit sum(1 for _ in sz.split_iter(text)) # increment: 0.00 MiB

Low-Level Python API

Aside from calling the methods on the Str and Strs classes, you can also call the global functions directly on str and bytes instances. Assuming StringZilla CPython bindings are implemented without any intermediate tools like SWIG or PyBind, the call latency should be similar to native classes.

import stringzilla as sz

contains: bool = sz.contains("haystack", "needle", start=0, end=sys.maxsize)
offset: int = sz.find("haystack", "needle", start=0, end=sys.maxsize)
count: int = sz.count("haystack", "needle", start=0, end=sys.maxsize, allowoverlap=False)

Edit Distances

assert sz.edit_distance("apple", "aple") == 1 # skip one ASCII character
assert sz.edit_distance("αβγδ", "αγδ") == 2 # skip two bytes forming one rune
assert sz.edit_distance_unicode("αβγδ", "αγδ") == 1 # one unicode rune

Several Python libraries provide edit distance computation. Most of them are implemented in C, but are not always as fast as StringZilla. Taking a 1'000 long proteins around 10'000 characters long, computing just a 100 distances:

Moreover, you can pass custom substitution matrices to compute the Needleman-Wunsch alignment scores. That task is very common in bioinformatics and computational biology. It's natively supported in BioPython, and its BLOSUM matrices can be converted to StringZilla's format. Alternatively, you can construct an arbitrary 256 by 256 cost matrix using NumPy. Depending on arguments, the result may be equal to the negative Levenshtein distance.

import numpy as np
import stringzilla as sz

costs = np.zeros((256, 256), dtype=np.int8)
costs.fill(-1)
np.fill_diagonal(costs, 0)

assert sz.alignment_score("first", "second", substitution_matrix=costs, gap_score=-1) == -sz.edit_distance(a, b)

Using the same proteins as for Levenshtein distance benchmarks:

§ Example converting from BioPython to StringZilla.
import numpy as np
from Bio import Align
from Bio.Align import substitution_matrices

aligner = Align.PairwiseAligner()
aligner.substitution_matrix = substitution_matrices.load("BLOSUM62")
aligner.open_gap_score = 1
aligner.extend_gap_score = 1

# Convert the matrix to NumPy
subs_packed = np.array(aligner.substitution_matrix).astype(np.int8)
subs_reconstructed = np.zeros((256, 256), dtype=np.int8)

# Initialize all banned characters to a the largest possible penalty
subs_reconstructed.fill(127)
for packed_row, packed_row_aminoacid in enumerate(aligner.substitution_matrix.alphabet):
    for packed_column, packed_column_aminoacid in enumerate(aligner.substitution_matrix.alphabet):
        reconstructed_row = ord(packed_row_aminoacid)
        reconstructed_column = ord(packed_column_aminoacid)
        subs_reconstructed[reconstructed_row, reconstructed_column] = subs_packed[packed_row, packed_column]

# Let's pick two examples for of tri-peptides (made of 3 aminoacids)
glutathione = "ECG" # Need to rebuild human tissue?
thyrotropin_releasing_hormone = "QHP" # Or to regulate your metabolism?

assert sz.alignment_score(
    glutathione,
    thyrotropin_releasing_hormone, 
    substitution_matrix=subs_reconstructed, 
    gap_score=1) == aligner.score(glutathione, thyrotropin_releasing_hormone) # Equal to 6

Serialization

Filesystem

Similar to how File can be used to read a large file, other interfaces can be used to dump strings to disk faster. The Str class has write_to to write the string to a file, and offset_within to obtain integer offsets of substring view in larger string for navigation.

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

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow import foreign_buffer
from stringzilla import Str

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

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

Quick Start: C/C++ 🛠️

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

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

Or using a pure CMake approach:

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

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

Basic Usage with C 99 and Newer

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

#include <stringzilla/stringzilla.h>

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

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

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

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

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

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

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

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

Basic Usage with C++ 11 and Newer

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

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

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

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

haystack.end() - haystack.begin() == haystack.size(); // Or `rbegin`, `rend`
haystack.find_first_of(" \v\t") == 4; // Or `find_last_of`, `find_first_not_of`, `find_last_not_of`
haystack.starts_with(needle) == true; // Or `ends_with`
haystack.remove_prefix(needle.size()); // Why is this operation in-place?!
haystack.contains(needle) == true; // STL has this only from C++ 23 onwards
haystack.compare(needle) == 1; // Or `haystack <=> needle` in C++ 20 and beyond

StringZilla also provides string literals for automatic type resolution, similar to STL:

using sz::literals::operator""_sz;
using std::literals::operator""sv;

auto a = "some string"; // char const *
auto b = "some string"sv; // std::string_view
auto b = "some string"_sz; // sz::string_view

Memory Ownership and Small String Optimization

Most operations in StringZilla don't assume any memory ownership. But in addition to the read-only search-like operations StringZilla provides a minimalistic C and C++ implementations for a memory owning string "class". Like other efficient string implementations, it uses the Small String Optimization (SSO) to avoid heap allocations for short strings.

typedef union sz_string_t {
    struct internal {
        sz_ptr_t start;
        sz_u8_t length;
        char chars[SZ_STRING_INTERNAL_SPACE]; /// Ends with a null-terminator.
    } internal;

    struct external {
        sz_ptr_t start;
        sz_size_t length;        
        sz_size_t space; /// The length of the heap-allocated buffer.
        sz_size_t padding;
    } external;

} sz_string_t;

As one can see, a short string can be kept on the stack, if it fits within internal.chars array. Before 2015 GCC string implementation was just 8 bytes, and could only fit 7 characters. Different STL implementations today have different thresholds for the Small String Optimization. Similar to GCC, StringZilla is 32 bytes in size, and similar to Clang it can fit 22 characters on stack. Our layout might be preferential, if you want to avoid branches. If you use a different compiler, you may want to check it's SSO buffer size with a simple Gist.

libstdc++ in GCC 13 libc++ in Clang 17 StringZilla
sizeof(std::string) 32 24 32
Small String Capacity 15 22 22

This design has been since ported to many high-level programming languages. Swift, for example, can store 15 bytes in the String instance itself. StringZilla implements SSO at the C level, providing the sz_string_t union and a simple API for primary operations.

sz_memory_allocator_t allocator;
sz_string_t string;

// Init and make sure we are on stack
sz_string_init(&string);
sz_string_is_on_stack(&string); // == sz_true_k

// Optionally pre-allocate space on the heap for future insertions.
sz_string_grow(&string, 100, &allocator); // == sz_true_k

// Append, erase, insert into the string.
sz_string_expand(&string, 0, "_Hello_", 7, &allocator); // == sz_true_k
sz_string_expand(&string, SZ_SIZE_MAX, "world", 5, &allocator); // == sz_true_k
sz_string_erase(&string, 0, 1);

// Unpacking & introspection.
sz_ptr_t string_start;
sz_size_t string_length;
sz_size_t string_space;
sz_bool_t string_is_external;
sz_string_unpack(string, &string_start, &string_length, &string_space, &string_is_external);
sz_equal(string_start, "Hello_world", 11); // == sz_true_k

// Reclaim some memory.
sz_string_shrink_to_fit(&string, &allocator); // == sz_true_k
sz_string_free(&string, &allocator);

Unlike the conventional C strings, the sz_string_t is allowed to contain null characters. To safely print those, pass the string_length to printf as well.

printf("%.*s\n", (int)string_length, string_start);

What's Wrong with the C Standard Library?

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

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

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

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

StringZilla partially addresses those issues.

What's Wrong with the C++ Standard Library?

C++ Code Evaluation Result Invoked Signature
"Loose"s.replace(2, 2, "vath"s, 1) "Loathe" 🤢 (pos1, count1, str2, pos2)
"Loose"s.replace(2, 2, "vath", 1) "Love" 🥰 (pos1, count1, str2, count2)

StringZilla is designed to be a drop-in replacement for the C++ Standard Templates Library. That said, some of the design decisions of STL strings are highly controversial, error-prone, and expensive. Most notably:

  1. Argument order for replace, insert, erase and similar functions is impossible to guess.
  2. Bounds-checking exceptions for substr-like functions are only thrown for one side of the range.
  3. Returning string copies in substr-like functions results in absurd volume of allocations.
  4. Incremental construction via push_back-like functions goes through too many branches.
  5. Inconsistency between string and string_view methods, like the lack of remove_prefix and remove_suffix.

Check the following set of asserts validating the std::string specification. It's not realistic to expect the average developer to remember the 14 overloads of std::string::replace.

using str = std::string;

assert(str("hello world").substr(6) == "world");
assert(str("hello world").substr(6, 100) == "world"); // 106 is beyond the length of the string, but its OK
assert_throws(str("hello world").substr(100), std::out_of_range);   // 100 is beyond the length of the string
assert_throws(str("hello world").substr(20, 5), std::out_of_range); // 20 is beyond the length of the string
assert_throws(str("hello world").substr(-1, 5), std::out_of_range); // -1 casts to unsigned without any warnings...
assert(str("hello world").substr(0, -1) == "hello world");          // -1 casts to unsigned without any warnings...

assert(str("hello").replace(1, 2, "123") == "h123lo");
assert(str("hello").replace(1, 2, str("123"), 1) == "h23lo");
assert(str("hello").replace(1, 2, "123", 1) == "h1lo");
assert(str("hello").replace(1, 2, "123", 1, 1) == "h2lo");
assert(str("hello").replace(1, 2, str("123"), 1, 1) == "h2lo");
assert(str("hello").replace(1, 2, 3, 'a') == "haaalo");
assert(str("hello").replace(1, 2, {'a', 'b'}) == "hablo");

To avoid those issues, StringZilla provides an alternative consistent interface. It supports signed arguments, and doesn't have more than 3 arguments per function or The standard API and our alternative can be conditionally disabled with SZ_SAFETY_OVER_COMPATIBILITY=1. When it's enabled, the subjectively risky overloads from the Standard will be disabled.

using str = sz::string;

str("a:b").front(1) == "a"; // no checks, unlike `substr`
str("a:b").front(2) == "2"; // take first 2 characters
str("a:b").back(-1) == "b"; // accepting negative indices
str("a:b").back(-2) == ":b"; // similar to Python's `"a:b"[-2:]`
str("a:b").sub(1, -1) == ":"; // similar to Python's `"a:b"[1:-1]`
str("a:b").sub(-2, -1) == ":"; // similar to Python's `"a:b"[-2:-1]`
str("a:b").sub(-2, 1) == ""; // similar to Python's `"a:b"[-2:1]`
"a:b"_sz[{-2, -1}] == ":"; // works on views and overloads `operator[]`

Assuming StringZilla is a header-only library you can use the full API in some translation units and gradually transition to safer restricted API in others. Bonus - all the bound checking is branchless, so it has a constant cost and won't hurt your branch predictor.

Beyond the C++ Standard Library - Learning from Python

Python is arguably the most popular programming language for data science. In part, that's due to the simplicity of its standard interfaces. StringZilla brings some of that functionality to C++.

  • Content checks: isalnum, isalpha, isascii, isdigit, islower, isspace, isupper.
  • Trimming character sets: lstrip, rstrip, strip.
  • Trimming string matches: remove_prefix, remove_suffix.
  • Ranges of search results: splitlines, split, rsplit.
  • Number of non-overlapping substring matches: count.
  • Partitioning: partition, rpartition.

For example, when parsing documents, it is often useful to split it into substrings. Most often, after that, you would compute the length of the skipped part, the offset and the length of the remaining part. This results in a lot of pointer arithmetic and is error-prone. StringZilla provides a convenient partition function, which returns a tuple of three string views, making the code cleaner.

auto parts = haystack.partition(':'); // Matching a character
auto [before, match, after] = haystack.partition(':'); // Structure unpacking
auto [before, match, after] = haystack.partition(sz::char_set(":;")); // Character-set argument
auto [before, match, after] = haystack.partition(" : "); // String argument
auto [before, match, after] = haystack.rpartition(sz::whitespaces_set()); // Split around the last whitespace

Combining those with the split function, one can easily parse a CSV file or HTTP headers.

for (auto line : haystack.split("\r\n")) {
    auto [key, _, value] = line.partition(':');
    headers[key.strip()] = value.strip();
}

Some other extensions are not present in the Python standard library either. Let's go through the C++ functionality category by category.

Some of the StringZilla interfaces are not available even Python's native str class. Here is a sneak peek of the most useful ones.

text.hash(); // -> 64 bit unsigned integer 
text.ssize(); // -> 64 bit signed length to avoid `static_cast<std::ssize_t>(text.size())`
text.contains_only(" \w\t"); // == text.find_first_not_of(sz::char_set(" \w\t")) == npos;
text.contains(sz::whitespaces_set()); // == text.find(sz::char_set(sz::whitespaces_set())) != npos;

// Simpler slicing than `substr`
text.front(10); // -> sz::string_view
text.back(10); // -> sz::string_view

// Safe variants, which clamp the range into the string bounds
using sz::string::cap;
text.front(10, cap) == text.front(std::min(10, text.size()));
text.back(10, cap) == text.back(std::min(10, text.size()));

// Character set filtering
text.lstrip(sz::whitespaces_set()).rstrip(sz::newlines_set()); // like Python
text.front(sz::whitespaces_set()); // all leading whitespaces
text.back(sz::digits_set()); // all numerical symbols forming the suffix

// Incremental construction
using sz::string::unchecked;
text.push_back('x'); // no surprises here
text.push_back('x', unchecked); // no bounds checking, Rust style
text.try_push_back('x'); // returns `false` if the string is full and the allocation failed

sz::concatenate(text, "@", domain, ".", tld); // No allocations

Splits and Ranges

One of the most common use cases is to split a string into a collection of substrings. Which would often result in StackOverflow lookups and snippets like the one below.

std::vector<std::string> lines = split(haystack, "\r\n"); // string delimiter
std::vector<std::string> words = split(lines, ' '); // character delimiter

Those allocate memory for each string and the temporary vectors. Each allocation can be orders of magnitude more expensive, than even serial for-loop over characters. To avoid those, StringZilla provides lazily-evaluated ranges, compatible with the Range-v3 library.

for (auto line : haystack.split("\r\n"))
    for (auto word : line.split(sz::char_set(" \w\t.,;:!?")))
        std::cout << word << std::endl;

Each of those is available in reverse order as well. It also allows interleaving matches, if you want both inclusions of xx in xxx. Debugging pointer offsets is not a pleasant exercise, so keep the following functions in mind.

  • haystack.[r]find_all(needle, interleaving)
  • haystack.[r]find_all(sz::char_set(""))
  • haystack.[r]split(needle)
  • haystack.[r]split(sz::char_set(""))

For $N$ matches the split functions will report $N+1$ matches, potentially including empty strings. Ranges have a few convenience methods as well:

range.size(); // -> std::size_t
range.empty(); // -> bool
range.template to<std::set<std::sting>>(); 
range.template to<std::vector<std::sting_view>>(); 

Concatenating Strings without Allocations

Another common string operation is concatenation. The STL provides std::string::operator+ and std::string::append, but those are not very efficient, if multiple invocations are performed.

std::string name, domain, tld;
auto email = name + "@" + domain + "." + tld; // 4 allocations

The efficient approach would be to pre-allocate the memory and copy the strings into it.

std::string email;
email.reserve(name.size() + domain.size() + tld.size() + 2);
email.append(name), email.append("@"), email.append(domain), email.append("."), email.append(tld);

That's mouthful and error-prone. StringZilla provides a more convenient concatenate function, which takes a variadic number of arguments. It also overrides the operator| to concatenate strings lazily, without any allocations.

auto email = sz::concatenate(name, "@", domain, ".", tld);   // 0 allocations
auto email = name | "@" | domain | "." | tld;                // 0 allocations
sz::string email = name | "@" | domain | "." | tld;          // 1 allocations

Random Generation

Software developers often need to generate random strings for testing purposes. The STL provides std::generate and std::random_device, that can be used with StringZilla.

sz::string random_string(std::size_t length, char const *alphabet, std::size_t cardinality) {
    sz::string result(length, '\0');
    static std::random_device seed_source; // Expensive to construct - due to system calls
    static std::mt19937 generator(seed_source()); // Also expensive - due to the state size
    std::uniform_int_distribution<std::size_t> distribution(0, cardinality);
    std::generate(result.begin(), result.end(), [&]() { return alphabet[distribution(generator)]; });
    return result;
}

Mouthful and slow. StringZilla provides a C native method - sz_generate and a convenient C++ wrapper - sz::generate. Similar to Python it also defines the commonly used character sets.

auto protein = sz::string::random(300, "ARNDCQEGHILKMFPSTWYV"); // static method
auto dna = sz::basic_string<custom_allocator>::random(3_000_000_000, "ACGT");

dna.randomize("ACGT"); // `noexcept` pre-allocated version
dna.randomize(&std::rand, "ACGT"); // pass any generator, like `std::mt19937`

char uuid[36];
sz::randomize(sz::string_span(uuid, 36), "0123456789abcdef-"); // Overwrite any buffer

Bulk Replacements

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

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

Levenshtein Edit Distance and Alignment Scores

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

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

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

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

Sorting in C and C++

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

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

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

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

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

Standard C++ Containers with String Keys

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

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

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

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

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

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

Compilation Settings and Debugging

SZ_DEBUG:

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

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

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

SZ_DYNAMIC_DISPATCH:

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

SZ_USE_MISALIGNED_LOADS:

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

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

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

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

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

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

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

Quick Start: Rust 🦀

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

[dependencies]
stringzilla = ">=3"

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

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

Once installed, all of the functionality is available through the stringzilla namespace. Many interfaces will look familiar to the users of the memchr crate.

use stringzilla::sz;

// Identical to `memchr::memmem::find` and `memchr::memmem::rfind` functions
sz::find("Hello, world!", "world") // 7
sz::rfind("Hello, world!", "world") // 7

// Generalizations of `memchr::memrchr[123]`
sz::find_char_from("Hello, world!", "world") // 2
sz::rfind_char_from("Hello, world!", "world") // 11

Unlike memchr, the throughput of stringzilla is high in both normal and reverse-order searches. It also provides no constraints on the size of the character set, while memchr allows only 1, 2, or 3 characters. In addition to global functions, stringzilla provides a StringZilla extension trait:

use stringzilla::StringZilla;

let my_string: String = String::from("Hello, world!");
let my_str = my_string.as_str();
let my_cow_str = Cow::from(&my_string);

// Use the generic function with a String
assert_eq!(my_string.sz_find("world"), Some(7));
assert_eq!(my_string.sz_rfind("world"), Some(7));
assert_eq!(my_string.sz_find_char_from("world"), Some(2));
assert_eq!(my_string.sz_rfind_char_from("world"), Some(11));
assert_eq!(my_string.sz_find_char_not_from("world"), Some(0));
assert_eq!(my_string.sz_rfind_char_not_from("world"), Some(12));

// Same works for &str and Cow<'_, str>
assert_eq!(my_str.sz_find("world"), Some(7));
assert_eq!(my_cow_str.as_ref().sz_find("world"), Some(7));

The library also exposes Levenshtein and Hamming edit-distances for byte-arrays and UTF-8 strings, as well as Needleman-Wunch alignment scores.

use stringzilla::sz;

// Handling arbitrary byte arrays:
sz::edit_distance("Hello, world!", "Hello, world?"); // 1
sz::hamming_distance("Hello, world!", "Hello, world?"); // 1
sz::alignment_score("Hello, world!", "Hello, world?", sz::unary_substitution_costs(), -1); // -1

// Handling UTF-8 strings:
sz::hamming_distance_utf8("αβγδ", "αγγδ") // 1
sz::edit_distance_utf8("façade", "facade") // 1

Quick Start: Swift 🍏

StringZilla can be added as a dependency in the Swift Package Manager. In your Package.swift file, add the following:

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

The package currently covers only the most basic functionality, but is planned to be extended to cover the full C++ API.

var s = "Hello, world! Welcome to StringZilla. 👋"
s[s.findFirst(substring: "world")!...] // "world! Welcome to StringZilla. 👋")    
s[s.findLast(substring: "o")!...] // "o StringZilla. 👋")
s[s.findFirst(characterFrom: "aeiou")!...] // "ello, world! Welcome to StringZilla. 👋")
s[s.findLast(characterFrom: "aeiou")!...] // "a. 👋")
s[s.findFirst(characterNotFrom: "aeiou")!...] // "Hello, world! Welcome to StringZilla. 👋"
s.editDistance(from: "Hello, world!")! // 29

Algorithms & Design Decisions 📚

StringZilla aims to optimize some of the slowest string operations. Some popular operations, however, like equality comparisons and relative order checking, almost always complete on some of the very first bytes in either string. In such operations vectorization is almost useless, unless huge and very similar strings are considered. StringZilla implements those operations as well, but won't result in substantial speedups.

Exact Substring Search

Substring search algorithms are generally divided into: comparison-based, automaton-based, and bit-parallel. Different families are effective for different alphabet sizes and needle lengths. The more operations are needed per-character - the more effective SIMD would be. The longer the needle - the more effective the skip-tables are. StringZilla uses different exact substring search algorithms for different needle lengths and backends:

  • When no SIMD is available - SWAR (SIMD Within A Register) algorithms are used on 64-bit words.
  • Boyer-Moore-Horspool (BMH) algorithm with Raita heuristic variation for longer needles.
  • SIMD algorithms are randomized to look at different parts of the needle.

On very short needles, especially 1-4 characters long, brute force with SIMD is the fastest solution. On mid-length needles, bit-parallel algorithms are effective, as the character masks fit into 32-bit or 64-bit words. Either way, if the needle is under 64-bytes long, on haystack traversal we will still fetch every CPU cache line. So the only way to improve performance is to reduce the number of comparisons. The snippet below shows how StringZilla accomplishes that for needles of length two.

https://github.com/ashvardanian/StringZilla/blob/266c01710dddf71fc44800f36c2f992ca9735f87/include/stringzilla/stringzilla.h#L1585-L1637

Going beyond that, to long needles, Boyer-Moore (BM) and its variants are often the best choice. It has two tables: the good-suffix shift and the bad-character shift. Common choice is to use the simplified BMH algorithm, which only uses the bad-character shift table, reducing the pre-processing time. We do the same for mid-length needles up to 256 bytes long. That way the stack-allocated shift table remains small.

https://github.com/ashvardanian/StringZilla/blob/46e957cd4f9ecd4945318dd3c48783dd11323f37/include/stringzilla/stringzilla.h#L1774-L1825

In the C++ Standards Library, the std::string::find function uses the BMH algorithm with Raita's heuristic. Before comparing the entire string, it matches the first, last, and the middle character. Very practical, but can be slow for repetitive characters. Both SWAR and SIMD backends of StringZilla have a cheap pre-processing step, where we locate unique characters. This makes the library a lot more practical when dealing with non-English corpora.

https://github.com/ashvardanian/StringZilla/blob/46e957cd4f9ecd4945318dd3c48783dd11323f37/include/stringzilla/stringzilla.h#L1398-L1431

All those, still, have $O(hn)$ worst case complexity. To guarantee $O(h)$ worst case time complexity, the Apostolico-Giancarlo (AG) algorithm adds an additional skip-table. Preprocessing phase is $O(n+sigma)$ in time and space. On traversal, performs from $(h/n)$ to $(3h/2)$ comparisons. It however, isn't practical on modern CPUs. A simpler idea, the Galil-rule might be a more relevant optimizations, if many matches must be found.

Other algorithms previously considered and deprecated:

  • Apostolico-Giancarlo algorithm for longer needles. Control-flow is too complex for efficient vectorization.
  • Shift-Or-based Bitap algorithm for short needles. Slower than SWAR.
  • Horspool-style bad-character check in SIMD backends. Effective only for very long needles, and very uneven character distributions between the needle and the haystack. Faster "character-in-set" check needed to generalize.

§ Reading materials. Exact String Matching Algorithms in Java. SIMD-friendly algorithms for substring searching.

Levenshtein Edit Distance

Levenshtein distance is the best known edit-distance for strings, that checks, how many insertions, deletions, and substitutions are needed to transform one string to another. It's extensively used in approximate string-matching, spell-checking, and bioinformatics.

The computational cost of the Levenshtein distance is $O(n * m)$, where $n$ and $m$ are the lengths of the string arguments. To compute that, the naive approach requires $O(n * m)$ space to store the "Levenshtein matrix", the bottom-right corner of which will contain the Levenshtein distance. The algorithm producing the matrix has been simultaneously studied/discovered by the Soviet mathematicians Vladimir Levenshtein in 1965, Taras Vintsyuk in 1968, and American computer scientists - Robert Wagner, David Sankoff, Michael J. Fischer in the following years. Several optimizations are known:

  1. Space Optimization: The matrix can be computed in $O(min(n,m))$ space, by only storing the last two rows of the matrix.
  2. Divide and Conquer: Hirschberg's algorithm can be applied to decompose the computation into subtasks.
  3. Automata: Levenshtein automata can be effective, if one of the strings doesn't change, and is a subject to many comparisons.
  4. Shift-Or: Bit-parallel algorithms transpose the matrix into a bit-matrix, and perform bitwise operations on it.

The last approach is quite powerful and performant, and is used by the great RapidFuzz library. It's less known, than the others, derived from the Baeza-Yates-Gonnet algorithm, extended to bounded edit-distance search by Manber and Wu in 1990s, and further extended by Gene Myers in 1999 and Heikki Hyyro between 2002 and 2004.

StringZilla introduces a different approach, extensively used in Unum's internal combinatorial optimization libraries. The approach doesn't change the number of trivial operations, but performs them in a different order, removing the data dependency, that occurs when computing the insertion costs. This results in much better vectorization for intra-core parallelism and potentially multi-core evaluation of a single request.

Next design goals:

  • Generalize fast traversals to rectangular matrices.
  • Port x86 AVX-512 solution to Arm NEON.

§ Reading materials. Faster Levenshtein Distances with a SIMD-friendly Traversal Order.

Needleman-Wunsch Alignment Score for Bioinformatics

The field of bioinformatics studies various representations of biological structures. The "primary" representations are generally strings over sparse alphabets:

  • DNA sequences, where the alphabet is {A, C, G, T}, ranging from ~100 characters for short reads to 3 billion for the human genome.
  • RNA sequences, where the alphabet is {A, C, G, U}, ranging from ~50 characters for tRNA to thousands for mRNA.
  • Proteins, where the alphabet is made of 22 amino acids, ranging from 2 characters for dipeptide to 35,000 for Titin, the longest protein.

The shorter the representation, the more often researchers may want to use custom substitution matrices. Meaning that the cost of a substitution between two characters may not be the same for all pairs.

StringZilla adapts the fairly efficient two-row Wagner-Fisher algorithm as a baseline serial implementation of the Needleman-Wunsch score. It supports arbitrary alphabets up to 256 characters, and can be used with either BLOSUM, PAM, or other substitution matrices. It also uses SIMD for hardware acceleration of the substitution lookups. This however, does not yet break the data-dependency for insertion costs, where 80% of the time is wasted. With that solved, the SIMD implementation will become 5x faster than the serial one.

Memory Copying, Fills, and Moves

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

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

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

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

Random Generation

Generating random strings from different alphabets is a very common operation. StringZilla accepts an arbitrary Pseudorandom Number Generator to produce noise, and an array of characters to sample from. Sampling is optimized to avoid integer division, a costly operation on modern CPUs. For that a 768-byte long lookup table is used to perform 2 lookups, 1 multiplication, 2 shifts, and 2 accumulations.

https://github.com/ashvardanian/StringZilla/blob/266c01710dddf71fc44800f36c2f992ca9735f87/include/stringzilla/stringzilla.h#L2490-L2533

Sorting

For lexicographic sorting of strings, StringZilla uses a "hybrid-hybrid" approach with $O(n * log(n))$ and.

  1. Radix sort for first bytes exported into a continuous buffer for locality.
  2. IntroSort on partially ordered chunks to balance efficiency and worst-case performance.
    1. IntroSort begins with a QuickSort.
    2. If the recursion depth exceeds a certain threshold, it switches to a HeapSort.

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

Hashing

[!WARNING] Hash functions are not cryptographically safe and are currently under active development. They may change in future minor releases.

Choosing the right hashing algorithm for your application can be crucial from both performance and security standpoint. In StringZilla a 64-bit rolling hash function is reused for both string hashes and substring hashes, Rabin-style fingerprints. Rolling hashes take the same amount of time to compute hashes with different window sizes, and are fast to update. Those are not however perfect hashes, and collisions are frequent. StringZilla attempts to use SIMD, but the performance is not yet satisfactory. On Intel Sapphire Rapids, the following numbers can be expected for N-way parallel variants.

  • 4-way AVX2 throughput with 64-bit integer multiplication (no native support): 0.28 GB/s.
  • 4-way AVX2 throughput with 32-bit integer multiplication: 0.54 GB/s.
  • 4-way AVX-512DQ throughput with 64-bit integer multiplication: 0.46 GB/s.
  • 4-way AVX-512 throughput with 32-bit integer multiplication: 0.58 GB/s.
  • 8-way AVX-512 throughput with 32-bit integer multiplication: 0.11 GB/s.

Next design goals:

  • Try gear-hash and other rolling approaches.

Why not CRC32?

Cyclic Redundancy Check 32 is one of the most commonly used hash functions in Computer Science. It has in-hardware support on both x86 and Arm, for both 8-bit, 16-bit, 32-bit, and 64-bit words. The 0x1EDC6F41 polynomial is used in iSCSI, Btrfs, ext4, and the 0x04C11DB7 in SATA, Ethernet, Zlib, PNG. In case of Arm more than one polynomial is supported. It is, however, somewhat limiting for Big Data usecases, which often have to deal with more than 4 Billion strings, making collisions unavoidable. Moreover, the existing SIMD approaches are tricky, combining general purpose computations with specialized instructions, to utilize more silicon in every cycle.

§ Reading materials. Comprehensive derivation of approaches Faster computation for 4 KB buffers on x86 Comparing different lookup tables Great open-source implementations. By Peter Cawley By Stephan Brumme

Other Modern Alternatives

MurmurHash from 2008 by Austin Appleby is one of the best known non-cryptographic hashes. It has a very short implementation and is capable of producing 32-bit and 128-bit hashes. The CityHash from 2011 by Google and the xxHash improve on that, better leveraging the super-scalar nature of modern CPUs and producing 64-bit and 128-bit hashes.

Neither of those functions are cryptographic, unlike MD5, SHA, and BLAKE algorithms. Most of cryptographic hashes are based on the Merkle-Damgård construction, and aren't resistant to the length-extension attacks. Current state of the Art, might be the BLAKE3 algorithm. It's resistant to a broad range of attacks, can process 2 bytes per CPU cycle, and comes with a very optimized official implementation for C and Rust. It has the same 128-bit security level as the BLAKE2, and achieves its performance gains by reducing the number of mixing rounds, and processing data in 1 KiB chunks, which is great for longer strings, but may result in poor performance on short ones.

All mentioned libraries have undergone extensive testing and are considered production-ready. They can definitely accelerate your application, but so may the downstream mixer. For instance, when a hash-table is constructed, the hashes are further shrunk to address table buckets. If the mixer looses entropy, the performance gains from the hash function may be lost. An example would be power-of-two modulo, which is a common mixer, but is known to be weak. One alternative would be the fastrange by Daniel Lemire. Another one is the Fibonacci hash trick using the Golden Ratio, also used in StringZilla.

Unicode, UTF-8, and Wide Characters

Most StringZilla operations are byte-level, so they work well with ASCII and UTF8 content out of the box. In some cases, like edit-distance computation, the result of byte-level evaluation and character-level evaluation may differ. So StringZilla provides following functions to work with Unicode:

  • sz_edit_distance_utf8 - computes the Levenshtein distance between two UTF-8 strings.
  • sz_hamming_distance_utf8 - computes the Hamming distance between two UTF-8 strings.

Java, JavaScript, Python 2, C#, and Objective-C, however, use wide characters (wchar) - two byte long codes, instead of the more reasonable fixed-length UTF32 or variable-length UTF8. This leads to all kinds of offset-counting issues when facing four-byte long Unicode characters. So consider transcoding with simdutf, if you are coming from such environments.

Contributing 👾

Please check out the contributing guide for more details on how to setup the development environment and contribute to this project. If you like this project, you may also enjoy USearch, UCall, UForm, and SimSIMD. 🤗

If you like strings and value efficiency, you may also enjoy the following projects:

  • simdutf - transcoding UTF8, UTF16, and UTF32 LE and BE.
  • hyperscan - regular expressions with SIMD acceleration.
  • pyahocorasick - Aho-Corasick algorithm in Python.
  • rapidfuzz - fast string matching in C++ and Python.

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

License 📜

Feel free to use the project under Apache 2.0 or the Three-clause BSD license at your preference.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

stringzilla-3.10.1-cp312-cp312-win_arm64.whl (67.0 kB view details)

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

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

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl (222.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

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

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

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

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

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

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

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

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

stringzilla-3.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (208.2 kB view details)

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

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

Uploaded CPython 3.12 macOS 11.0+ ARM64

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

Uploaded CPython 3.12 macOS 10.13+ x86-64

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

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

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

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

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

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.10.1-cp311-cp311-musllinux_1_2_armv7l.whl (196.8 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (293.8 kB view details)

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

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

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

stringzilla-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (230.5 kB view details)

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

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

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

stringzilla-3.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (208.2 kB view details)

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

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

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

Uploaded CPython 3.11 macOS 10.11+ x86-64

stringzilla-3.10.1-cp311-cp311-macosx_10_11_universal2.whl (121.0 kB view details)

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

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

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

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

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.1-cp310-cp310-musllinux_1_2_i686.whl (206.7 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl (219.2 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (290.3 kB view details)

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

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

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

stringzilla-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (227.4 kB view details)

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

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

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

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

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

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

Uploaded CPython 3.10 macOS 11.0+ ARM64

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

Uploaded CPython 3.10 macOS 10.11+ x86-64

stringzilla-3.10.1-cp310-cp310-macosx_10_11_universal2.whl (121.0 kB view details)

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

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

Uploaded CPython 3.9 Windows ARM64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

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

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.1-cp39-cp39-musllinux_1_2_i686.whl (205.4 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (288.9 kB view details)

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

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

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

stringzilla-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (226.1 kB view details)

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

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

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

stringzilla-3.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (203.5 kB view details)

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

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

Uploaded CPython 3.9 macOS 11.0+ ARM64

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

Uploaded CPython 3.9 macOS 10.11+ x86-64

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

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

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

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.10.1-cp38-cp38-win32.whl (68.3 kB view details)

Uploaded CPython 3.8 Windows x86

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

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.10.1-cp38-cp38-musllinux_1_2_s390x.whl (197.7 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.10.1-cp38-cp38-musllinux_1_2_ppc64le.whl (222.2 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.1-cp38-cp38-musllinux_1_2_i686.whl (204.3 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (287.7 kB view details)

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

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

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

stringzilla-3.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (224.9 kB view details)

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

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

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

stringzilla-3.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (202.1 kB view details)

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

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

Uploaded CPython 3.8 macOS 11.0+ ARM64

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

Uploaded CPython 3.8 macOS 10.11+ x86-64

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

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

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

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

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

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

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

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_i686.whl (202.4 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (286.2 kB view details)

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

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

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

stringzilla-3.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (223.1 kB view details)

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

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

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

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

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

stringzilla-3.10.1-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.1-cp36-cp36m-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

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

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

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

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

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

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

stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (194.0 kB view details)

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

stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (222.6 kB view details)

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

stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (218.5 kB view details)

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

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

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

stringzilla-3.10.1-cp36-cp36m-macosx_10_11_x86_64.whl (78.4 kB view details)

Uploaded CPython 3.6m macOS 10.11+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 2635c22e908e5385ef227ba3e718579661d38e37c20d4e3cb48b505f04930c30
MD5 448243b0b42b0a903340351a90074d4d
BLAKE2b-256 0352146f056cd398100c389c1ab8d9551868630e6059a30bddbec1f7164b4768

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 5644fa595a716200d7b565442d77302194ac99737a5990405b2bbc352afa0244
MD5 45ab5295b243621e61381eb826f8c199
BLAKE2b-256 2788c16677f48743c5f6f0bdb271777865207cd5ac145d073c8a155033f73a58

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 c63c76655a83762457d8a8fbb7633441da2c8c7cc69e76456a0dd475a98ee46e
MD5 ed3df60128f3871d4ebd639d544c8133
BLAKE2b-256 57bb043fd96535f25b9df201219656b0c160c60457704ba43cb32fe3c2e7aed6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ee19478ac1805f56113cb1a12d1fd56f43f71311dbcc98c265eddc55d85b7fbb
MD5 aa479b18754196a45026648d65ae3885
BLAKE2b-256 970ae4c25969ee7321910574fe04d9bdb77c1abf0b22833d76daceeae7a3f2c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 9b7bd817b202dd2aea918f2f60dee60f806b01addf813c93ccac3d75ae805939
MD5 03812e366788dbfd7ed2a28fe7ac5fa8
BLAKE2b-256 8354bbbf119d63eb50f26f76bc04370b8c1a14851a3b16dac62a8751759f49c3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 a60a83632d25e2d151a4dc0939cea21134121723eb28f1004f0120261266463f
MD5 9bb109442bc702eb7a51b51eaf04708c
BLAKE2b-256 1f7ea36469279db456a8ff929638606d4da00b6aa5079fff9ab478e65c71d7d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 0db5a237670dc6d15b521ed4a7326bb57220131e40a900e8122a41fc139761b0
MD5 d53c72d83a2627db2e417e4c948d4edc
BLAKE2b-256 8e57160377892b1054ae6a9d798b0f13f47a4cf69dfedb75efc16a9328add223

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 87c3ff3371891baab99cdcf136a8ab94a3795aaf6ae1ce5189e9241b1360b42a
MD5 225f62faa441012f1cee214c7408560b
BLAKE2b-256 151e631e9ea268060a5baabccbdfefdcbb59f49843f0b48c7e6358fa9ac8b05d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c4b00f15efdd51926c7ec4957281e765b1d9ff7bcb1d2585203dab91479eb9bc
MD5 9d31da9103a18397c8bee93c6407dd68
BLAKE2b-256 2ba267a9dcc92352ef02db9da284b6278e17dac9c1feff91d202ef4e5fd1b55a

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c6b3eb7c9dd5d9cb3a24a8deda10851047d13f79c5ee30f63b6e526e768ddeab
MD5 f196e4ffb8cd0ab3258d730bdf84c60b
BLAKE2b-256 235b221613f8e92786a87ac8c5a0307b5152b34d8bec92ae3314f8ccd2558c8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 95da65b611e53ab6494ce455796c89c7d91270b3da554b6310c8536dff03b428
MD5 5e2f797e7388a2e1c382e9a54f809f8c
BLAKE2b-256 1e567c6a42a09f24f51165cd6395bc1296ac84d6825cd03a4398b2fd7a7705f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 c789e91eb497486a0d02197566506fb3b28f203ddfc314b8aa10c67d8ec572e0
MD5 8d2277f86fe4510ad7c80d2c5d671c02
BLAKE2b-256 02134baec9763aacb43f145ba9dea6ff9f95f5ad520186f0a3106474239fd47c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7e633fab64a56895ed538770a74f14b066c20caa717b85bb083cc1e9e29b849d
MD5 fb392824ebfaf675777a78482328f467
BLAKE2b-256 f1336c168c914aaee8df046532160ab26152918c120bafa560a4286f47fe58ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d97519a73f0ad54b230357f36036da96181704c8de7dc37612ac32b24666052b
MD5 aa11ebb6dade77aa5411f953155ac0c3
BLAKE2b-256 353e8b9140193f76c95d41de00924f2a5303e5a26a6882b286cac7b835169aa4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4ad9fc4714f90c1b9ccf4418ce5482dc797155e18610f1cf5cc7b8d8e0979c40
MD5 0ab059d6adbb965eebac61f98d9681be
BLAKE2b-256 533bce98c401c22dcba951347302e945945229c5d783fd487cfe79b8619c0d53

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 7d388ebebc047a8bc456199a8d4fab953372434d12cee8b669d3897c66f2b81c
MD5 dbd71caf4bed9fda66ac712538112d6f
BLAKE2b-256 f3743e4c0f5080092f87f1c480f58f34f30fe2c8eadcf2b454d1cf6cbf672681

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 2b22fee12dc878aba7d0f9337654fc0e2fafc0eafc416ef4cada994c3e1de469
MD5 0202bd98edfe5fcaf43ba48494e00313
BLAKE2b-256 17dd53db980aeaf081a7c7b6409ad6a04162dd6ac492af5dd4f684f61a4fb353

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 beee873132dcfcd38634b1d1dc6c913672170a1384fefd34dbef13008246ec2b
MD5 0446a6c8ef0865a0aab70f3667cfd617
BLAKE2b-256 d046fb4510ebe6affca6331f0ea1b2cafa1c5629c7b38c881cc5f3611ba8d8f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 ee85a94b783ddb9f46475c1b95fb34d97b98dbaba71ec59d9087dded314de02a
MD5 e840a445cb5224726725cd87ec339555
BLAKE2b-256 fcc0fd623dba7d18ff0390a76275e4866ebefc3a3d3d39e9ffbd2dcc48e321e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 eb95cac49a3036a1ee207ec0ff42ac7c4cbff56b32799c2acf4351f944d290ab
MD5 c2eeb8dce2d7f8bbc88d3ed15fcd2b3e
BLAKE2b-256 1c3a2635fd7cfedc0bcdb079986499b9079603a1f97d79fdf22f0e8d3431c5fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 21b11fe99d99e82571d108e52a3442f6a4755aa515241f18e2e49ed57606a40e
MD5 be97e5c2c359d8439bf0a5df43e5945b
BLAKE2b-256 73024da13500d330a0caefd9332d6a7fa16668d03a68da8c61f3137a96fadfc1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 ad95268a2e303039a0adc5ed516cf195319767cbe376ef4dbdbcf9ff5e5296a9
MD5 5bbfc3e5262e64a22924ba647a42e1de
BLAKE2b-256 fc8025f93a23ae958c8a9d5d7390cdef55dee71c7161e9c6b50f5e33e808b991

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 add41757e32b782d37e87adc1adeb12aa26107794a83f30a54605da1bac08ae7
MD5 23c876186b2c2c4dd62a2ebf787b0138
BLAKE2b-256 2a386a5a03e78195b9162f6ebfe1ed1886234d49d696b5b60f918856e9cb3292

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 e9659ed38d10d78431bb89a0f38d0a848f68c89b1da568f34deeebc70157326b
MD5 0538f57b37a01c44b0746833671508aa
BLAKE2b-256 794ef10760b744aff382307c3f08bd8c19e21f8f7255b54150162831501477ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 c8251a57d5a6b28f9fd26bdef4aad6c5d12d8da4683ae57d804f8bce5b769f7f
MD5 d4d905356e0b2286103c3a4faa7d3f04
BLAKE2b-256 6dd1e2d0dccc9388a2247e3848bedd586a78aecff2436724f2b51f64c038b482

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 93a3409d158b8b7708879808b83b8ba6f554ee8da3f8c3b40930a7779a8a37af
MD5 67c55ea67a989d380a6ace2400f27ecc
BLAKE2b-256 48a460bf8a8e7aae974d6d3ae835c58a83e37b996557075834866e3432953b16

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b14b3f905dae91fdad5dddc640527364d4acdeea3875afd715414a73bd1b5c32
MD5 818124f58e3adf6c1bae06c07d1907f6
BLAKE2b-256 b735990cf44d5b3e4532c5b151349296c2fc6714c64f943ec927938d183cee35

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 6f00b119967d430f8a0058702c3f6501f8605fa7eafdf1dd3defd20d3ef1cd9c
MD5 34428ee02ac1819bc3f5dc0376123b9d
BLAKE2b-256 30c09ec6cdb742ed6039e15fb579f8dc48940e35de5d45e1ed29411fa212a092

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 f5556d6af78c5a4fab50a83784dbc62c0bf513afbaa184aa534e072392073db5
MD5 4354ba96d9966273679aa29a5883db8e
BLAKE2b-256 f129446505aa778093f288e8dd99055b4334ed92cd6157ab5df2d768c88b624c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c1d59c22a810af050d03a7acc3ab6f0a5926e011e26a59ce791a6e3d9bd89130
MD5 ba70b282b82d5f0c6eadfe8c37e96e46
BLAKE2b-256 3b667be56be02309e0cd4f6ca37b9bef91380bce9e18186f3b2bf7da108b78fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 dad726278832eededf31568828d98e9254419cb42ff573d8b09bf1052ac04dcf
MD5 54522e5ff589af0517395d9d607005b2
BLAKE2b-256 d7f9599ed36091defd3fec07371aeb885b7887eb900c0b3ac611a7fd28b39e4c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 67001bb6629e037e68d75964ec329c01bc6a0d1b6516f3ee2eb3cd6fd4449cd2
MD5 cd2a57429940ed016ee2dca16f509e4f
BLAKE2b-256 5af2981b6fc76cebba2da686c2e39d079da503875371acc6545fd5d2319e4042

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 1b858f6c9f86fe3fa54c295d86639305812fa4291b07422a92aafd4f742c118b
MD5 169f48d4643b8cc90c7ec498fee71a5a
BLAKE2b-256 22a832b37be5150e5025d9a816955c28e0c110a072581b8f393c4842c66d500e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 7e9c3b55271eee7e1398ead7d7b184602bea59697a1545cd2c92c041e0393189
MD5 03afca6bd0ef51828c940be49f6a78be
BLAKE2b-256 a64b5c8d5c876f5d096a589c7312bf237e283a9e4f2251c96a3b08a543c4cf5c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 dc8759790f60119d5702740f50ab7ec3bda80fbc057b198ee77c0116cf872e01
MD5 a75aa2e47bb841ff957e3b71300b6075
BLAKE2b-256 6b984722c4abe8dfef340f273169cadc6688c8c24182397900f0bc941ae889c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 d44facc629a2046224efcfc15985a975162146eceb70c1fdcc6308e1cfd5eb31
MD5 d7ff0d796ce9700424f7b2e4864021ef
BLAKE2b-256 16acd3a80ad147733db1ce7fc7b54221e04af00d7ac15c74373f4be700d1011b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 8b9fd2a4e694df38dc3f7484948de1c190847f296057c8290ac3218861f08f20
MD5 00cd5aa6cdb8b1e62a42d6b3cedfc6a2
BLAKE2b-256 2b8c182a27259f43961eb640473ec76ff68661f6312a74a9a3762ad09416e19a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 544c012f22104d1f5699e261c710e8e1e62e0de70b7e4daa5a010c6b333b48b5
MD5 f0def15c1f6cd23361deb2b9b60f5d4a
BLAKE2b-256 54585636bd2b2800c88f8deac77be31360a51e359c0b803a0f15ecedb0c9ad87

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 b22b350a74a09b7fb2dad43d9dffcf0bc79203e2180eac9481e1f0f0ce90c36b
MD5 48fc5113cc08951ace0b607cfb57f595
BLAKE2b-256 2f294612890c04d7a3b40f24dc531a240e60e40f66b46598671ba743ad1b13a1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 b83c84d3b8336f2413d99f63bd1c87644da80386b9832775564643311e86773e
MD5 014117b53c4838d61574cf03ba21c7e5
BLAKE2b-256 b30d1e43adc0af1cdd66fee81da112ccbd1c398e4f4980e80e292860be10ab94

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 fac39b45efacba138a63de3d000b59aceb87aea790d373bb6ba97a8d8064ff02
MD5 806bcd1ee912a335ce14bc0f3ece74de
BLAKE2b-256 c17a9eee6068dc8626c19b4424a75b5cafecd300c80ef9ee0441b60c867af552

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 842a46e0af18364fdeaf6805d246f169355468776762348c78b8b33aef4f0e39
MD5 db64fd01f2db7d2325c3981c770d2bae
BLAKE2b-256 14a1fe9a75b054b1a7436a9347e83ee0154278719988687c411956003a639091

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 3d2281ef9cb21425b041356b8a7ed9759f3273739973329673eefd7d2d0d4f94
MD5 bae2780263d5d05e3b78ea794ef117a5
BLAKE2b-256 1626bc35956464dca2b0e41d36953444b0a5a6690d286e0211c0f1757408a067

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a76301f7778625c8f95d78e78afdb09241dc7d523b819ac5cf9118e14482a765
MD5 731b87b4ba70a3f032e142cef393d2f8
BLAKE2b-256 7feb17c2fb407979dbb347912cf1903ecc2bff2f1a315ac735f29b45a2f2e0ab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 5c72b67c83c3ee3ca18e4d73593e46c31cf16e36473f00a41ff872c3c2b7a772
MD5 0948cc09121cf4301168aa8b66d383c3
BLAKE2b-256 ec36af1801bb241127a1671914e6189aacd82bb92590299e5f60ed94ad093a9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 3584f4885d773ce853977bb029adf9d5d0ac6cb5d1db44600c61e3c59eedc989
MD5 d0f1dd6cd20df503fe7e0a19eceb34b0
BLAKE2b-256 fe9605fa8a86168149990745ff63869ed1105bcb1613918259040019dae41fc6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9928f60e8e8b82a6d9f88fb2606b0825d42b80e323b8f249345994ca14f17711
MD5 b3de372a80bb0cecd9a05a92517bf0f3
BLAKE2b-256 d1651882782402ca79a95577064c76ade408d2365e6a7a036357c292cd74de05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 43cd03b97a2d4b8141e8e77062ebb079a41b5f73143ce74af05a68bbbe9130fe
MD5 b51fc0cc3f5a27930370d6aa85b92a86
BLAKE2b-256 db1762b4c4158c17cd3c7af34e688ad370bdad75060545dee65862d1490cada4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d91ed1bbb5296192e97dd61ae98309b9fefbbbd7693724dd9b7be52d53f0a565
MD5 327eabcf74827aec87a91ebdde908ece
BLAKE2b-256 57dc160dedbf08e33ca035eac02a1fa42450603721678332ac132139985d5d99

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 5e2f43f223d1983a8a6eb45ac2224d2b09f9eaf6eda472bbf76fb67626c86f3f
MD5 d7cd00cd696336b1cf834be4b95c36ea
BLAKE2b-256 0a5172c18c716129eda7636a82206328253957d2293e6c836f39b0df4f3f9996

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 bff85988654b3385ff01d7447aa87e23a5d6fb900593f7b922bc59e7461e50c5
MD5 ba666bb6541ccaf248bffe73b665bab2
BLAKE2b-256 eaa13558d29e31b13d9fdfe26e0ea42ae4b82e20d8b99f94c08821af2d59e573

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 a35b942e9e97e9e02937285cd31be947eb889af98c0a194299128ab31994b9d1
MD5 5780cac14f040f52bcbcb93862eb0137
BLAKE2b-256 c5e1ccf3972f3c54e3202d952a67af5bc41084b3c6030a17317aa49fa7afeb1e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 9269771710ef88b179cbcea45b10816e176fca0b25495df9c7a3a526f842bf48
MD5 ca31375eea8da2a0cece127532ffb1cd
BLAKE2b-256 c8da68ccb9a4297fff843938a7190e96e24275545c8cdd2ffc105c03e118be02

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 e1a129588095cc3fc77bd18a00299283e505abf7cc2d26d8bf91eb299e466381
MD5 8e75ee8b3457bf378e85536596ba1cfb
BLAKE2b-256 b8b28e0b699dbe57a05388ec35c7195e02b30847e34e183a94c787e684854597

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c7c3a6e54e3e26da6f3fef08788c09b6cae775b252a6110bd7e786f59f73ead5
MD5 dad7a9805ec621c6db6e9913b4be6619
BLAKE2b-256 0ae1174dc8c1fa7fe7e125830fa2d4d06152b1aab1ccb49c6a3d21f4a47cda29

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 1d8814af1f3e3dc66a8d9441e7a14062cd7d68b1224216f5ae33b912a684a784
MD5 82104d1f467274499144dc29852b1b31
BLAKE2b-256 d472da807f8c85ac4d570b8c98737a3311d5c3388b9fb6aa252899403497b4a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 0e0ec85d7deb7990aabc681c89a755a17e1979156b7fe7a2ca94e7fcf6af13c4
MD5 e434b902498636a73304716589a50888
BLAKE2b-256 20102b28314fb5863d5abe6d9b0f3b443708638493d7a14c0a8d04cdda239b24

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 16de1cd1364a23d892bcf7f638c7e9cc6a769b5d40b24e89ba2296faa32f8476
MD5 db76e8bddf31cca3a2cce1af5cfe1e7a
BLAKE2b-256 1ba2cf5fb94fe233af4ed3ecfea7a0cde12245b1e73ec392189a13041546e57f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 7451a0e306a5844693e9fc768a1cbac2223828f17f0d5748a78a4d9eca130da4
MD5 1f92016c9a8c919683155cdb33ef9508
BLAKE2b-256 bce9b69a0ea2936abb882b8bc4259d95fbce022148b13d11884013d7e95b39c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 15ca571709f00f3a3c1380759e701dd7737c77bc6ad90f4287c867fd736e936b
MD5 9575f128a1e285925446120a95787b46
BLAKE2b-256 56e0997601b3739dbfae85030991bd3d0d3f77b76a43ccd84406a07e173b2e9b

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 419c13e4cdc2be7e218f4ce362ef9d471bdd4b6ce1a62adb7358e5c59739ec71
MD5 55d437baa6ae812b0a42ebd88ecba3cf
BLAKE2b-256 b4301fec27f0983367936c812ad81595d6a1efd58ba742cd74b2bf6a9f71264e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 07b49b30ab6bf7fb4bff24c4fa8bef3e6cb973e212563f2983081005c8caf7e2
MD5 f21740ad5298ab4de2f004d42e7f64dc
BLAKE2b-256 af7cc04ff2581ca15f13bccf4c71cf89774230cebd69b432b03f9464fa4f3b4d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 074e7b21837ddec502000cc378f8c1641dde2269cab2f0c180cb78f6e78ad00e
MD5 0ec3280a0c130c0c16f0fb97a3fe5233
BLAKE2b-256 96f0ea4e4e4631ee1619eceb826e15395b2b4d60962a07136cb450836fa806ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a78f41004db14ebe232f70715ea2d197e4f5bad23f7ee7b94ac2232c5cf7fe72
MD5 accb3b01b123911022b6c013138404be
BLAKE2b-256 6264ad28eff519551a27049738d6669cc463ba1c862b1405358d14390a8e5f15

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6a4664d9f2908530317c603c967ed28f69867f7f815b48a22a5c698b456807a0
MD5 b8330569ff64dd2a7ea3afcc14a44089
BLAKE2b-256 f39e12a04d3e68a77c4fb394378bc23844aa3a81871721bc65f57320f41688d3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0dfdf864b20375c2794a040b852892636b1a77e04d0afdf4f1aef3106b9c69c4
MD5 219d69d6e6339862561b6dda26936c80
BLAKE2b-256 316fb97cb8006a682f2cc35743bc9a2d4b9bff1b5e8d79b098505b0bb5a60b42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 061bf406c3e8c9479d04eba4fa79d8e785001a1d07a8f35c01351a3e01ebfd73
MD5 bb915b5fde26b4b03e53712197154a75
BLAKE2b-256 d9116f16143dc98981520493bd119f24fa80da5c6c12922a33603f5812d2ec23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 10c626a7ea5adf1919c7f6a2d3c807c514ee830954a37cfe879e743fff692a44
MD5 633e6930f95304852dfa0ccdc63712e7
BLAKE2b-256 64a81597de245bb9571f6174a1e94b1d880d044763352cd1d3dc446203abc2c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 56351529561b1260c78ce1d3a97847be776407df37f0d85373763a7296909bf1
MD5 e957832779aa845f797a3d00ca9ec2ae
BLAKE2b-256 0e940fad0fc6409e71dde0f1f47218f40d8fc9ab7abab7732f02881666017163

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.1-cp38-cp38-win32.whl
  • Upload date:
  • Size: 68.3 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.1-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 fcb784f6a4d0e5b11ddc4fcbe61141429e9e8de2c53f56b4a6ede22067066dfc
MD5 91ca496e4cc7c0b9b67a4ee171acd77e
BLAKE2b-256 159abd36220c23bb87a2601f8e5b2cf42d39a6d4b669fe3d0eaafae82cfed703

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b315921d28fe7ac5ac17afd84f3c282809c97e1f8aafb1784840d3b5a70498e7
MD5 d467e7852bc28b824ee2981c247e6cab
BLAKE2b-256 4ee499a23181b0ef0a4b3e544d73cfd7f55919c9f0d68d1f5040366fdceca45d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 cd114854b9799559125b2f55a4131030e822882e0fb9c8666e8218a2b6191898
MD5 2e72116b0f4fdbeda9c1eef92113e784
BLAKE2b-256 33b82984ecd1a63e36f5c05fc8e93854f99f5cb9517098137e2e9fe8460c4d70

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 b2e1fe0427965f7fd755d6e8cdefa186b537ddda60999d4088e2dc2fbcd296da
MD5 a3412aca9f977f50bde31101c9341303
BLAKE2b-256 48193fc083863af78c4ed23e5e5e24ba843dfab17c9d8bd79189f512b3dce60e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 7e63b6f66e42a588f646e202df3d8e1bffc649bf58991b6282bd0f1520b59f8a
MD5 51dfd15cf584a0cb2f5cde29ab5299b8
BLAKE2b-256 d7121eabee87dfae6f1e36cfc0c6306883f8cf39a1eea708eb16d12236dc31b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 24d4932cdfaa9b0c7a557ec748fcbc76d3fb9a6b5d5b38c12eb2987070519815
MD5 adad18ae51146f96d457e19a63b1187e
BLAKE2b-256 083bb68aaf5fc8357c03237ee35032da94b42e281f8733f7146891cf8ade88c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1171f23a5377038f08800132ce20d2d74b784d18f535bc0b462f2ab3661a1ae5
MD5 35ad5f657aa5d0476ef8c3b0152294e9
BLAKE2b-256 cdc107079f928436999c99c280e40025832f65271b228dca50da762c8a620f91

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b10d811116757ad339b2bee9c7957e1db10e7e624b25b52d2434fc74ec01879
MD5 720c7ea6ef14cac282d3396ed606251e
BLAKE2b-256 143c83da144c77a81c23b154e97026a6430e3b406c1e1df94f7f35bb9318a1c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 658b899872c5f47b119d2e7f95c994d20eaabaf9de6c997ae4d62e34fc48fdc8
MD5 afe3f2fdb51c88dcc33f7d667d5a5db6
BLAKE2b-256 227f9925843b2e07420a6598a5eb2911ea009884b0a4ce66c108efd78b620f44

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 daf7d0e3c76f7eaa6ed6b9ada68a3f99873c9890bde4949a9cd962eadd059379
MD5 16637759290466628013053887f0f806
BLAKE2b-256 2e470916c890ddf05f1ef3a44148ac1f4fc16959f3107d6d13faa9f7ce663c02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 97cb4e83e02c6159a41586de68929a6ed1075c65390b6b951f62af7ebb40e56d
MD5 22f471d4abd05f7c96e070257c39253c
BLAKE2b-256 1e43858b639e64b35eda92609744118fb458de38492c3192916e21489619e176

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 a8851befcd7cfbd526a5b6fd198e5e6b3a7afb297cbf457baacc962a6d6adb94
MD5 21a5696158a0a5ee228e99a611c999b1
BLAKE2b-256 13baf7d61f895a88a781c43de0c7a916d068d3b51f2240c9266484820576a01a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c43e7e192bd197f50e789f57db1f800e0c28a42187993d81dbd26a484df9dd0e
MD5 3eada0d88745371eac30c371f0b0d024
BLAKE2b-256 b5e553daf37df8bebd213d46ad66e0dca95ddb9e8a420e2db0423e1d8b0b1158

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 1c94b3f957fdb4887c71d33b4b0f1a18e53443377b76dcb1f824194e2b9c0024
MD5 829fe1d3990a9494decbe8985039ce2a
BLAKE2b-256 4d21ae82ac8c02588c9ab01eba2cca6e7c2aa87d9c163cf3f4702a675b15e30f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 77b7dc6a73d66791ce408bc775e579db444be5d93245b4f9f49ac36c5a55b93e
MD5 79bf488c7fd55b93b41009910656dd99
BLAKE2b-256 5cebd9ef57cc3ea66f72e114913634527c43fc052826f174d82c3ab36a640cbc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 54c6a4725a883551df3c295436d689d2140e7d5bd1248d3ea77ac51e27d4d201
MD5 3652a98115afe952a875ee41c8e13cf5
BLAKE2b-256 4e5c9d2b681e85c3bd314a22bb6a599dad0eb2de9ed75489de33e25db20106ea

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 29ae0e1fa574da469354a249435f25098bbf26d66195cf92d0ccc105c35c9a99
MD5 b15b6c31075c10c7e9d72a32c7abf5aa
BLAKE2b-256 ef0ba427b700adca1fcc8eb0a1a2bd51eb3df1b07c295ea91ed438a6349acd5d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 24ce9f1357ab135b5324e682bb3b6b21ac152ae12cb37816ad44298c6e7130d6
MD5 541e8f0566783bf20dc228c9dd238e49
BLAKE2b-256 9c10b75a0ad5cca35e193949dacf5e36af6cae59ea0ca8e9ee12eb94e17632e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 95151d6ed619423d2e5ac109b8827343c03ef2dfd9a4779cc249178122d98528
MD5 bb2a168d50ba9eec144cd8f7bd13451e
BLAKE2b-256 c34a1dad74c480eed75bf079d4d47d0abf79e7d889b75eb85c2a634f5ef8a887

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 543a11bdc974dd061efed7ef36ed6c471ac30465baa673ae1551d4faf3af7d3e
MD5 e244d0001ae75b131c549e1087d0e17d
BLAKE2b-256 8e5aeed17fbb75ddab55652f52b2957397a8671422ff174cf3f45c9d49acda72

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 43881b37183bff2aa25988ca2f9aef8b0f3ad14c39b318ba0cac893510af2bb6
MD5 fc92d19007e82e13b9c59ec249482703
BLAKE2b-256 fcbb25bd1812d29c7e56c286a4412de9a6e6f941c918b51672aa7ea7bb18524c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 ef5e011495cbf61da879ae338c6465223f7305a919121c049dd89a3ed112f850
MD5 6ae12f10fb1683d0dda1b9c41e873edd
BLAKE2b-256 43eb3491b9b4228caae3b509a24c2d35a88d1aeff7d7e776e3e7ac4b1ad1ccf4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e6d050347e7a2c039d203f206245b57253da42a63c20daf5a86f40ea086e971b
MD5 a59124e693ec46eaeab0d68e0b0a713e
BLAKE2b-256 bc0c26ad5aabec7a21b32ebd7f97e803e5131669c93955654dc2f7576d578857

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cd5743569afe03d4936e00103f978f5b2c5e2e37cfc2959539f77893840b6dbd
MD5 23a33675252905629a015b3668004fff
BLAKE2b-256 f641b1536ac28c890ac8ec318e2d11cbb47efc9ba3b19ad56a930c256043e106

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 15b848da67683e86d13cf48c367d60e10465bdac70389e57821ed726c09e680a
MD5 8538307a65142110576be7a8974c85a9
BLAKE2b-256 273291ae2ed8ad19577d05669e38b54fc6c5c811c2477a9479bf1c7e70976997

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1619248e5321c9344007a64a4011424ef3c519a196e03dbf035bddd4276d2ee1
MD5 f4117e11b00f11c5bf6d0ce0712935d2
BLAKE2b-256 a54cb06a7621302f9818085c089b08ee5e23f2ffc5b19035397e220eba827860

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b56e4cf5392ba430bc48a4c508378a0dd3dce216e152b866867b478917fe8cf3
MD5 0353ac6bf6db83d9ee2c3ffab238f3b3
BLAKE2b-256 be3e22474b355300e2729bd859bf17a9ba547f27932a150ba8dd08efc3d5c78f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 84bd3e842d130dbdd4f2097967c3098e046ec3d7e03fe9ab7ac57284ec8040f8
MD5 db1be4ef43c0299ff5964051abbfcd03
BLAKE2b-256 8cdbe659d3285d3b7d72142d9f606362a64e8cfb759c390efe3a2d57ed38df2e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 cf31a255541a3e5ea1eb12017923462100c7c6d241dc29d427ddd7683f2f7473
MD5 60ee25f75f137603eb2c30936026f9ab
BLAKE2b-256 3ecb44388c5124f98136a28433848d049d470a63fd24b13819b2e61f2ec5269c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 b1c3a482238b4581d94295fd8d617e32558fd7bf966e891bd923186ce05964b6
MD5 2f05b5b8085b7bb99ffb4df7bdd940c5
BLAKE2b-256 7db5db7ae10a7fbfe5c7e6aa85dfbd37d6fe3456da51ceb8af009cc6b1904ae5

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 27c470ec435dc4894241157adf35a05461ac785a4560c258dc5aec0c0e0835e4
MD5 63a97eb9fea7ddf62e79f69d55e2d8cc
BLAKE2b-256 6ec748dda794a25314c1818613e2edfaf0b580437b57421b56b317e21a8f1082

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 fe43faa842416014404333eeb320aaefc122d112181a852598e0841bfae33317
MD5 e17e4e0f1947edca645c43b0e9de8676
BLAKE2b-256 208fd734b7ef5af6ccc2b7d28f7ba27379c523eede65cf103fca03c97a615c36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 34891b1df5c8db2cb25e6293cc775d97c751aae8d9f3f49e42c0d532c724dc50
MD5 fff554deb5e58504ce69067b46131b7a
BLAKE2b-256 b897f4333e3bbcdc7000127727d65e4fc4f2e749a5c8362422abde8433d961cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 f5bc246930ad695fdf9bd11e67243bf9b07d4c214dd5bfe920861a1b7942bb34
MD5 cdce0248d39701c725d282098837d3d7
BLAKE2b-256 f1acd418b76b7967e3a85bf356950324d68685478c737832263c6ca9decefef3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 495fca3b8f7a5ab114f857af743a485ff8103c3906ef46f87f53f2144dd97a93
MD5 fa5e18bf88d1beb513d9aa5fec397ca3
BLAKE2b-256 44b278770eb60e8dd41bc0622d008817bee6216cc31aa64069f38e67a2e24533

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 a537ba3cdcaae178fa1634a12898545b1a3301862ac5c3bb70ddbcd7cd14b8b2
MD5 79be0afc237a5481ced83d0bd7b1fe0c
BLAKE2b-256 3a7b67bdbdd8024275ed1f46ae353874ddf088fb26da4be2a3a59eb770f33d97

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 9f31fb84cd9084fd43ba075da971ee356a72826a8115894f6bd729cc7ce316fe
MD5 7228671f4aa617661050aa3a59e58b9b
BLAKE2b-256 b5ab178f2c8d86e710bb3ef0bea7d8f34673034ac270a7a99a12430b0857be52

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.1-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.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 801efed709e9ab079160a0eea800e6d51784da206244ea6d26172f702e9ff9b7
MD5 575c5b26641033d71f2f102b04ff871f
BLAKE2b-256 62a53e4d8bad58872748ff329dd878f390a0845dee5a00543ef7e9a244c800d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 106505ce7ed0371a710fabf2d30fbddcf9f597e132e130429f0043474a6d9602
MD5 45c7613db022d426589fb15f67757ee7
BLAKE2b-256 23d0078df3e669d6ce3fdc3dcd417fcce9aa6d6cd9e2c5dd297b5114c0df978d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 139105f2fdd5a20312a3a5aaff21d92a51746152563adc251d8a735f0b760bab
MD5 f6c720a059a1b22769d41072820fa325
BLAKE2b-256 9fde6170975c9587ea9079bddf73928f2825ecbdcbd77db21cfac1eda6873b6c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fd0301708cc12814acbe4d65426a09e7ab8352e331a01679c3c9e26f6628a496
MD5 b369aabecd1be2bc0db45380f06f6d26
BLAKE2b-256 e21dc5a3da5395c47bfd27b09532c86baa2178aeb63082e9e12b3b043806133a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 37ce8c1a69cef88524695ce25d501782ace809b88c6ce620c95ad872d1972c59
MD5 7575a823005cb622863675d3efd94fdb
BLAKE2b-256 6e8f367ee4ea1f887bab962e3628d253ef87aa0853599634d4ec214ab1f0b21c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.1-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 2881ffcba25e7a434b56dbd5bdc22a2f0c645acdec20b03e1ccfbc02594b4739
MD5 32e0688b1e453379273cba905c037ada
BLAKE2b-256 268d0de0224fa2477115faef34ed9f3c4b98a24e1d81a04d5d5b437444d2386e

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