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
std::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
std::transform
x86: 3.81 · arm: 2.65 GB/s
str.translate
x86: 260.0 · arm: 140.0 MB/s
sz_look_up_transform
x86: 21.2 · arm: 8.5 GB/s
Get sorted order, ≅ 8 million English words 6
qsort_r
x86: 3.55 · arm: 5.77 s
std::sort
x86: 2.79 · arm: 4.02 s
numpy.argsort
x86: 7.58 · arm: 13.00 s
sz_sort
x86: 1.91 · arm: 2.37 s
Levenshtein edit distance, ≅ 5 bytes long
via jellyfish 3
x86: 1,550 · arm: 2,220 ns
sz_edit_distance
x86: 99 · arm: 180 ns
Needleman-Wunsch alignment scores, ≅ 10 K aminoacids long
via biopython 4
x86: 257 · arm: 367 ms
sz_alignment_score
x86: 73 · arm: 177 ms

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

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

Functionality

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

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

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

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

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

Quick Start: Python 🐍

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

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

Basic Usage

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

from stringzilla import Str, File

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

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

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

Basic Operations

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

Advanced Operations

import sys

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

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

Character Set Operations

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

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

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

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

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

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

Collection-Level Operations

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

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

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

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

Iterators and Memory Efficiency

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

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

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

import stringzilla as sz
%load_ext memory_profiler

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

Low-Level Python API

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

import stringzilla as sz

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

Edit Distances

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

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

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

import numpy as np
import stringzilla as sz

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

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

Using the same proteins as for Levenshtein distance benchmarks:

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

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

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

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

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

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

Serialization

Filesystem

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

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

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow import foreign_buffer
from stringzilla import Str

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

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

Quick Start: C/C++ 🛠️

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

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

Or using a pure CMake approach:

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

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

Basic Usage with C 99 and Newer

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

#include <stringzilla/stringzilla.h>

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

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

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

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

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

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

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

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

Basic Usage with C++ 11 and Newer

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

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

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

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

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

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

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

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

Memory Ownership and Small String Optimization

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

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

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

} sz_string_t;

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

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

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

sz_memory_allocator_t allocator;
sz_string_t string;

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

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

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

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

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

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

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

What's Wrong with the C Standard Library?

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

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

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

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

StringZilla partially addresses those issues.

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

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

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

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

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

using str = std::string;

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

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

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

using str = sz::string;

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

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

Beyond the C++ Standard Library - Learning from Python

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Splits and Ranges

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

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

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

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

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

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

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

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

Concatenating Strings without Allocations

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

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

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

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

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

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

Random Generation

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

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

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

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

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

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

Bulk Replacements

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

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

Levenshtein Edit Distance and Alignment Scores

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

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

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

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

Sorting in C and C++

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

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

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

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

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

Standard C++ Containers with String Keys

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

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

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

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

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

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

Compilation Settings and Debugging

SZ_DEBUG:

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

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

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

SZ_DYNAMIC_DISPATCH:

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

SZ_USE_MISALIGNED_LOADS:

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

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

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

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

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

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

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

Quick Start: Rust 🦀

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

[dependencies]
stringzilla = ">=3"

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

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

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

use stringzilla::sz;

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

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

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

use stringzilla::StringZilla;

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

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

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

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

use stringzilla::sz;

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

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

Quick Start: Swift 🍏

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

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

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

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

Algorithms & Design Decisions 📚

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

Exact Substring Search

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

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

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

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

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

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

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

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

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

Other algorithms previously considered and deprecated:

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

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

Levenshtein Edit Distance

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

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

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

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

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

Next design goals:

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

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

Needleman-Wunsch Alignment Score for Bioinformatics

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

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

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

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

Memory Copying, Fills, and Moves

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

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

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

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

Random Generation

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

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

Sorting

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

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

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

Hashing

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

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

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

Next design goals:

  • Try gear-hash and other rolling approaches.

Why not CRC32?

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

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

Other Modern Alternatives

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

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

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

Unicode, UTF-8, and Wide Characters

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

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

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

Contributing 👾

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

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

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

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

License 📜

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

Download files

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

Source Distribution

stringzilla-3.10.6.tar.gz (183.0 kB view details)

Uploaded Source

Built Distributions

stringzilla-3.10.6-cp312-cp312-win_arm64.whl (67.2 kB view details)

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.10.6-cp312-cp312-win32.whl (68.4 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl (289.6 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_s390x.whl (205.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_ppc64le.whl (228.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_i686.whl (210.6 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_armv7l.whl (198.2 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl (223.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (203.2 kB view details)

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

stringzilla-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (231.5 kB view details)

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

stringzilla-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (228.1 kB view details)

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

stringzilla-3.10.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (295.3 kB view details)

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

stringzilla-3.10.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (209.5 kB view details)

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

stringzilla-3.10.6-cp312-cp312-macosx_11_0_arm64.whl (80.0 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.10.6-cp312-cp312-macosx_10_13_x86_64.whl (79.1 kB view details)

Uploaded CPython 3.12 macOS 10.13+ x86-64

stringzilla-3.10.6-cp312-cp312-macosx_10_13_universal2.whl (121.6 kB view details)

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

stringzilla-3.10.6-cp311-cp311-win_arm64.whl (67.2 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.10.6-cp311-cp311-win_amd64.whl (78.9 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.10.6-cp311-cp311-win32.whl (68.3 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl (289.1 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.10.6-cp311-cp311-musllinux_1_2_s390x.whl (204.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp311-cp311-musllinux_1_2_ppc64le.whl (229.0 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.10.6-cp311-cp311-musllinux_1_2_armv7l.whl (197.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl (223.8 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (203.2 kB view details)

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

stringzilla-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (232.2 kB view details)

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

stringzilla-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (228.2 kB view details)

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

stringzilla-3.10.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (294.7 kB view details)

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

stringzilla-3.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (209.5 kB view details)

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

stringzilla-3.10.6-cp311-cp311-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.10.6-cp311-cp311-macosx_10_11_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.11 macOS 10.11+ x86-64

stringzilla-3.10.6-cp311-cp311-macosx_10_11_universal2.whl (121.2 kB view details)

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

stringzilla-3.10.6-cp310-cp310-win_arm64.whl (67.2 kB view details)

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.10.6-cp310-cp310-win32.whl (68.3 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl (285.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.10.6-cp310-cp310-musllinux_1_2_s390x.whl (201.4 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp310-cp310-musllinux_1_2_ppc64le.whl (225.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.10.6-cp310-cp310-musllinux_1_2_armv7l.whl (194.5 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl (220.6 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (200.3 kB view details)

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

stringzilla-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (228.8 kB view details)

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

stringzilla-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (225.5 kB view details)

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

stringzilla-3.10.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (291.4 kB view details)

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

stringzilla-3.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (206.3 kB view details)

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

stringzilla-3.10.6-cp310-cp310-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.10.6-cp310-cp310-macosx_10_11_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.10 macOS 10.11+ x86-64

stringzilla-3.10.6-cp310-cp310-macosx_10_11_universal2.whl (121.2 kB view details)

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

stringzilla-3.10.6-cp39-cp39-win_arm64.whl (67.3 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.10.6-cp39-cp39-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.10.6-cp39-cp39-win32.whl (68.4 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl (284.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.10.6-cp39-cp39-musllinux_1_2_s390x.whl (200.2 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp39-cp39-musllinux_1_2_ppc64le.whl (224.5 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl (219.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (198.9 kB view details)

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

stringzilla-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (227.3 kB view details)

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

stringzilla-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (224.2 kB view details)

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

stringzilla-3.10.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (289.9 kB view details)

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

stringzilla-3.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (204.8 kB view details)

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

stringzilla-3.10.6-cp39-cp39-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.10.6-cp39-cp39-macosx_10_11_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.9 macOS 10.11+ x86-64

stringzilla-3.10.6-cp39-cp39-macosx_10_11_universal2.whl (121.2 kB view details)

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

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

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.10.6-cp38-cp38-win32.whl (68.4 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl (283.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.10.6-cp38-cp38-musllinux_1_2_s390x.whl (198.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp38-cp38-musllinux_1_2_ppc64le.whl (223.5 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.6-cp38-cp38-musllinux_1_2_i686.whl (205.2 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl (218.3 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (197.7 kB view details)

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

stringzilla-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (226.3 kB view details)

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

stringzilla-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (222.9 kB view details)

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

stringzilla-3.10.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (288.7 kB view details)

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

stringzilla-3.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (203.4 kB view details)

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

stringzilla-3.10.6-cp38-cp38-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.10.6-cp38-cp38-macosx_10_11_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.8 macOS 10.11+ x86-64

stringzilla-3.10.6-cp38-cp38-macosx_10_11_universal2.whl (121.2 kB view details)

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

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

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.10.6-cp37-cp37m-win32.whl (68.3 kB view details)

Uploaded CPython 3.7m Windows x86

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

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

stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_s390x.whl (197.5 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_ppc64le.whl (221.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_aarch64.whl (216.0 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (196.0 kB view details)

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

stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (224.7 kB view details)

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

stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (220.6 kB view details)

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

stringzilla-3.10.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (287.1 kB view details)

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

stringzilla-3.10.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (201.5 kB view details)

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

stringzilla-3.10.6-cp37-cp37m-macosx_10_11_x86_64.whl (78.8 kB view details)

Uploaded CPython 3.7m macOS 10.11+ x86-64

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

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.10.6-cp36-cp36m-win32.whl (68.3 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_x86_64.whl (281.2 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_s390x.whl (197.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_ppc64le.whl (221.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_aarch64.whl (215.3 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (195.2 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (224.1 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (219.8 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl (286.2 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (201.0 kB view details)

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

stringzilla-3.10.6-cp36-cp36m-macosx_10_11_x86_64.whl (78.6 kB view details)

Uploaded CPython 3.6m macOS 10.11+ x86-64

File details

Details for the file stringzilla-3.10.6.tar.gz.

File metadata

  • Download URL: stringzilla-3.10.6.tar.gz
  • Upload date:
  • Size: 183.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for stringzilla-3.10.6.tar.gz
Algorithm Hash digest
SHA256 7a7d0479d58f9acb8cd86e25366a67725711c13cb13a11ce2b76ef79ac1c7de5
MD5 20906545b9cde74711a1b041b7c08b1c
BLAKE2b-256 927c01bded895b9f4d6f82040f482b5d297f76c9ecee81f6b056155981b7ec8c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 e10f91b37810571c4a080f96b9114bf59806fd99191d1bd69228d7a1db97ec31
MD5 917ef5f4c4e72477e2d71ed12453f969
BLAKE2b-256 20a282bc87d9ba611db4d653ab7fd039a3b7b78add421d810a267f54dbff3864

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b309f9f11c475869f6bc51de00c12a5a89ade9b9ec446fdd0fc70f6c9cddf48d
MD5 1e266bbbcbf55bf48ef36b7b070671d9
BLAKE2b-256 fcbb8c4597039282fe3224fedb357dda632d82c322ceee0e0348fd2ed610aff6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 16cd60fe58415cd987b85625dc317d1a5d0e51c6bbfc7662ebf154e3c8d52a58
MD5 955a5fe8476de1f03cad3eeb05460b0a
BLAKE2b-256 2570398f1fcd6f9409bd969ae04f4e3b0df7f0afacac1e08c0b5444a7b169d19

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 70ba6b7e29671f6fdafc350bb550cf7ca493c80323ff5a41a863f2e9b22c907e
MD5 3c731310c241a109a8e48e918d7c6168
BLAKE2b-256 03dc8d9c76a9f018fccea5665296689393186b34c84d7d5fa65ffa1b97989769

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 7cb901a31fe7304e02eda829e95c83f6ccb4487554ad8cfcf410dcc98f2df4fb
MD5 fd7c3d0df0c79180181aa4f845405fe9
BLAKE2b-256 c4dc1cb0d3ea9c7c1b653140fdce214f317311916e4a4fbb2fc4ea10980f6474

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 136e9f523e85eb2a4a858e3f60c6ff5f3ec8a7bd7bedf0cc2e25348cad9b96a3
MD5 18fc9ea6e9b8fd3abbb3339155b7cf52
BLAKE2b-256 e19b07f6361f4dd801ff473f81fe7f50ded3b214b7f4dc3f61e5fd91d08b93ca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 23112b60444bfeaba22d8d6b870ee3d92022116eb90946c7e903395a9ef8b6f9
MD5 c4f5f656a47e0b869110d3632f875762
BLAKE2b-256 ece5df14535013b16d62d5aef2f10db53acc5be603be348c21e3a0b4d1d19fa0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 95395eaa4ba62d1b74d26750f0541a955f61a318e1e37f9cc1f10f8173756e77
MD5 02f947e463f0d629f558d342869392cb
BLAKE2b-256 94b41afcd7ea5795873abb30e9ab6845f60f871b76c900d972abbb3deb0911a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 08b08bd543a7205cdc192085f2e31ea1ba809f5393f41ba394980fe7e9a10963
MD5 f7aea5eb373508da003422bea9613172
BLAKE2b-256 f94b4656821209b9c40738f063afe518280d9454dda4ecaa6f0e332b5b35d622

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 d6b65a759b2c27a0531bc209c7610adcbda734697d63bbc8d840bae25f3cde22
MD5 11b1336d540d6afa59b2ac69e9beaa41
BLAKE2b-256 25de8afac89594b1f5dacb7557cdacc4d27212a96b055d6d3ba09a667424c85e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 0c8597e2d6bb669e4977c01927c27519bb57092cd00ac76b27b3b52e967c3a65
MD5 7c309ba30862f894e2c8fa448a4edcf0
BLAKE2b-256 7df592b898e203008b2cc618606e71a2b29d43f04c40dba14085e634521a6d7c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5c19ff2e89c92d86f7adfa8f99eec2dc7366e39088030ac493a1884990768c0e
MD5 032ed9ef76f5362d79c1d546fe0ab482
BLAKE2b-256 7daabcdc8f6b5f99ecda623e759d5a4586cf7ce724ba36a57795e30a98c2ee7b

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9ca172368e941c0b5c03d5ea7cbfc8a4b4bf42dc28e657dc65acdd0b4a9f2957
MD5 f2307aa9747629ac91738d3f71fe41e5
BLAKE2b-256 16b626f51d7ddb9fbaec14f5c301bb1eac2eead793a952128970ddfb23cb7ed5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 acfd052452845f952eea3623b129e6583777ea4571ea19151aec9484cced1b43
MD5 bb92fd7bb230ec5187f3c8b15a5bfe49
BLAKE2b-256 f88be520e9d1fe42f46f8b81cf28e55355054c6d05701ecd40c466229fef3797

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a3556313be8c110bf438fa76c2dc12cfdf2285ce5c885a1adfeb297ebd89ba7f
MD5 ec0f52b47fa9eea24cef256f34eff61b
BLAKE2b-256 42bbf1646f33707e240692ebfd48c858ed52ed012533856b0e18c5cef6d29fa1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 81465549a9c241dd025f3e2b5cfb064a8ac9ed63b803c87e5d886f7f0ead69d2
MD5 ec6b548e07609a463ae3988d31e02752
BLAKE2b-256 25f750671074601fa7610230dcb6b448ccb8b3756066bde0d57957408f41dda5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 c63e634396f59d5e232fdbb2b308ec80e7136fbdae25788182d0d992ffb9da87
MD5 a36bf4eab5672de5df9f890322877866
BLAKE2b-256 e7a663158d8b911fa810b444292d8b3de6a846cbbb4c843efcd129733bd158f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 47ccd93fe798547bc6690a87b95bee9384950ed4ec58cf1f7dee076fac8535b6
MD5 8e4ee240923b594974139a4b202b17eb
BLAKE2b-256 4160fa57d9e096225b5c5143b9b37cad14e092866cf2e941f65a4c9c8e1ef444

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 8d3c4a3ee56b6e935c00ab309646caaeeac733fdcb67eedea380fc1fbc309df5
MD5 07971a4ad348afbf712ee6df6f4c382b
BLAKE2b-256 6da01601b29c906dd55bdb81e0ca5b197e496c501d95844244a2a0365ba67be3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 da04d5a431025ed67801d0fd735c3801154d1eb7718dfe4c3cfc5a8ff7a47782
MD5 7a74ec5c075d80e36a5e9ae89b2dadaa
BLAKE2b-256 9446b18674fe4773febe86bc83d120373f86405ab710c574132278df5cfb67ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d848796a5a6a59b734a8219b842f7487f5dc61c531d2e48993040653b57e42a8
MD5 fad55dc4a2f8d61f1ead61fcd3642231
BLAKE2b-256 db39f432bf158db558cf132ac4e3f591afc7a1e88de2a31f9007f3728b5a15cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 1e029f09355bec0b2c0b7ce9b6ceb144cecbbe5916d53bdba201b0059549e875
MD5 2149bcd494711f6c4aa3bf69c00efb7f
BLAKE2b-256 369dfd31df1860f3297436c921af137aa9a07ff38b840e1b679e63180149b9c7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 cad38b91919aa8a1fd1d4b98e5346250518bf972892357f54fac1acd830cf6f4
MD5 3ecc7cef4942ee87547ed66c37ea6928
BLAKE2b-256 cccd804e8bf032417007896fb6832afa3716cf2b5f9d43054ef90abc0547bcdd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 5b1d6a50235d418b796df377009b5d8fd01067b1407f03c48f65717d2c049add
MD5 bcd7b13b0089fbfc0409f63eb4498104
BLAKE2b-256 d89bb5a1d016d3dd923921a9fcc10a9351355110097383a786c3b8c991a3e4dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 5a47c3f7a7fca9fbd3cd90f7f8ec05c68a20014cc99d322bb2db1b4a48cefe22
MD5 aa908baac298ef08ee6c39f19e279527
BLAKE2b-256 5410b4760574f738f9c2f4c7ee6520613605b22f889309a710dd24194c6dbb68

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 fb25a466234dc02e828fbf74bd84b4342b1aa0af991d4b1a8f2a772112ccb176
MD5 3d9b555400a78fb1aee35eff9e6b3de3
BLAKE2b-256 93678fcb288bed66b0f3e43147e7e1bf2793108696d4a20c2bb9a05a29c2cdc3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 4ad089d0aaeddc87ee677a619263544613db070f3a4eaee2d4f57daa5b00c6a7
MD5 647a6379be6baa3aae7974beb5cc6b89
BLAKE2b-256 7228f71a32064128cd83e2f5ae922c2c60d75e739871b8042d836332f342accf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 30f9737360e4d903b26c40282be940b8ccc1082a8721831d71d2852999a96a85
MD5 96c7f39708a378c7b79d1b9c387aa97c
BLAKE2b-256 b55e5aac8496498801054d54d8656dc5be1c219789b7dc4d999028ac71228e5d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 161fdf88b88679e506ed773d37782512e643c244aeae2f532658e88b8fc4f6fa
MD5 a28bcf8aaf800b4185a171c9cc177666
BLAKE2b-256 63e3bb84081f678463581abd14c5ad852ecd43430a3a61fe7d3e9eb1754ad79f

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a1f2f2b09b3bb2a8e2dd943950e814100c5db27bf46c53a767997a2ab1aec073
MD5 d0edf270e6136827c9f313bfedea94b6
BLAKE2b-256 ba98beef4500698f25877a931af80362874d0585a5c6d507f5c53cbd87683b76

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 097429f3cbad32ffa730a7b1299ea05104dc273e8abf6b2e5604e125f92dd928
MD5 2cd4b86255dd1b23c7dc75381efe7320
BLAKE2b-256 14409cd451af52a9cbb7110124e9eda3fe5aea66f771f5552c5b578bd9aabea0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c35b825c91fc5ac8e68cae2db4e63aebb923baf999eeca68ef42d0d663abb4d7
MD5 aa3ff428e5dfbd14831c39eb9ba2b36e
BLAKE2b-256 1002835a235410fa3bb06532eb3669ef3f23fabe6265374904a232f0a8c4062c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 2b7cd93d88092c8da2dea48bae8625de1b83b3bbfb11b4350aa2660dcd2424dd
MD5 b443abf32928cebd677a6d204bf0106d
BLAKE2b-256 35592da11784f0bd05e5d74f1eca6440c305cb43f0f04d3e899d1c4e7d64482a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 50be8228e557145cc2ab79895cced921a26c96627e4c56f253f46046f1764bcc
MD5 2694f2e6fe94b5d754ca41983fa74f64
BLAKE2b-256 7c7e36ba607f166bdf3d2bad111759057da37cda26d03dbc69400661945790ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 66b395bc784f64396f6f89ad93470e38d4809c5ac47dd7766796908036b9c66f
MD5 dfb687014a91fac95ea009ad41ad888e
BLAKE2b-256 798aabaaa354eabe3dd17a22e0f192f603e2360311003f420b86beb025b41bd3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 74408d7168a70102928a6a2e5188b62a13cb11464a0384b1ccf5181c71b2de34
MD5 37f925e919232b48c6eb46e8402410bc
BLAKE2b-256 f288c2f6e5abbeb1878a561cd8d997e7d8e450ea826774bf0cf2d0fe5f8f6aa1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 438f9273df286745940ebdd978f6c37b6d641c899139263e565dabcd4c0de69d
MD5 624866383e725a51e655e30faaced45f
BLAKE2b-256 8d0144725dbc60a56f637a22fc88c08ae5d26404492a7169457df068c18933c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6b410b87bb069bc11a642055aba9b785ec62dc5f6f60c7ba779ec147e866746a
MD5 bf471c792667162c1d9ffe6539722291
BLAKE2b-256 296f077d66b58fefdaaf2a9f4e902075cd9fde88c6d73a49b832d142f4f9810d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 1246b6a686c7edb4abd7fc36812417cdde504e19533c171c42d2cbb375e4b328
MD5 a76b422f09fc2ee272b9bfb8d1adbb15
BLAKE2b-256 69691249403d4aba705890cd42d47683fe92af3c56bc53d330b24e008c310c34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 bbbed04a9a6fe628f6722d5fbaa1e5b98a42a689e0355e2732d2d68171527923
MD5 c8dd323f5a9cb403bc0fb390e5ff988a
BLAKE2b-256 c83ed3ffd03ec7cca2dfd9184f746a45ccc3e9ba30150edf1a102125106d5e8e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 97abf75cce461408d517ea5b3b0ffddf6538f305d47fc353fb1546257f73e9b0
MD5 d7046e20de617e9275b99d9b855a6a5d
BLAKE2b-256 af3907e40eac6ac00a1fcfc3a047211ff702a29a0766398061c42c964f0bbd1a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 15d3988a4ff81c7a2365c0b7044f306538c88bf5ce7170e452d5117b84aace32
MD5 efc56f85cf450567a9e9ddac32b6d8a7
BLAKE2b-256 daaa05984510b890fac1e740d73faac2bd9e3915bda44bcc82c272fd8f0a892b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e8c19feff4da1a4386a5b31f824e82bbb23e232f8dd5460d67492b8d6eed8069
MD5 1393ffb213c5f87dd12520f569dd8e31
BLAKE2b-256 15e1dd4456ee36f85151923d215dfd35f55374a9fb67f8e5dc8392e2387985d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 7ea1715e381e0ead7b67b2edcc2e085d40dea34a9351e3f82edaf5225367efb8
MD5 32513ed849402d2f8c1d270111ac4d9f
BLAKE2b-256 6e4986675eb727a67eb6358bac0d0d44717abf1b1790ea27058e7fc1a795cc67

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 5aaabc7ea11d0c4cef43bdad008f2af70c4a51baa18615bb546c058154002256
MD5 ff0e5e079ef036ac8713b2808c227bcc
BLAKE2b-256 20b34c6c2a9a9003164b8342b7455dc80c1aa8d17ad9bd6d0a8491139c01fbf3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 600d89b5c883975f23d8749b7a566f99c5cf2e678b293797333935665b87300c
MD5 564a80f7db5a350d5febc865a151556e
BLAKE2b-256 bce3f4576b52931536bd69d1b51cc970434267b88bf2681ea5525fe9139dbdeb

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 95cef5a10bd7e1e5b7cd225b34e6a06edaf0eee33ea8a8f1311935789a4e234e
MD5 7e0a55aa1cecfa44488c300914909135
BLAKE2b-256 072215465d0b4997df787c85b31ba2906b0ffd61875f4759715b0d4bcf8f4838

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3d2a09c9faa3822c36744bc318073c78d7d57ec01c9b0b6ffd923ee4787b2292
MD5 534528e921eaa4033cb6758605c95779
BLAKE2b-256 eefbc0c12bd9fd6f30c467798858d93c7b196f03b252a49d616ea7444a6cf648

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5971c3c21be9ef54e854044b4c9fa506394644f5b802baf964ef7d4ca284fe93
MD5 fc6de19840e31dca897be00752415537
BLAKE2b-256 78e565d9350ff0d3a68022c4b352e42d9aff53c66f7663d54bc723cee90e9ee8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 5e6192c3aeecdb45db51261811380675c1d02d491cd73244246f3e48e9229674
MD5 cf56847842e90a74c84854a8b0ac79cf
BLAKE2b-256 97705f8d4129173381fc0db21a5bf0fd2217a8f610e915d2702867ac3c9e5156

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 617160dd08498cd1d2cb0c57b76a1f7d244f8bc06122bf56583b7bb752a9eaff
MD5 d147bdedb15c3465816ae5c452d2911e
BLAKE2b-256 3987111f03854698050d73d944a4e380512334d064a3d3ceaba38f6afa1dc43a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 7bca1d25911208da94921a3f3058470f3426adc28af925d820f6c0a2466c18e5
MD5 e8536651a3e5d1bd9ec296e7a95438ec
BLAKE2b-256 d254ea1e0dff099f6badec30955c7a89e6acfd747bb9adfc3598e448a7048441

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 00fed71faaaf1a7ad9682cb8fd1e92d8409946d7aa62c114200033ca84279c07
MD5 59c5914d896fdeac2b180850235e9fa2
BLAKE2b-256 3b65f927219fefb6d91399f43bc0045ff273dd007dee1a88437c80f2323aee88

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.6-cp39-cp39-win32.whl
  • Upload date:
  • Size: 68.4 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.6-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 31707f0e5228c14e5e27e7aa1d281e6f4ff85dc68546aad1a2e4fccc3355ed80
MD5 25b86a540fd455acd249bb1bfd9c7444
BLAKE2b-256 58d5e559083cc0a69eac7d627d6b74ceec75006b8e8e26f45431353932f536b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 def5be195d61737cc45b11b2fbbb7baf12540c4c3742d6449a6312f4fe21a66e
MD5 8c8885c361836f1f61ea52b9dbf4b81f
BLAKE2b-256 ab38410166d1bc8a836c36928014ee21f6a38ce82fb87a4bd37cacaf0fc1d242

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e6610dc04608c6620ddb9acad11815b4e2ee470a404305b73f259dc5bbb2f97e
MD5 bfee37e39b6065538f1cf089fdd244d5
BLAKE2b-256 78f5de126355717b550b75d56643da318212e6520a75805af290e51c8c02f841

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 3d47e67ba6745c649ecc254cc7f46f24941483bbdfd23e79c785cd0f15b71517
MD5 6662abadeb6e3fe3a77417e825b9561b
BLAKE2b-256 403ada40a9b283fd891e10555cd7393ee6696524dda73a8798fcfd0b2cfe16c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c6de62727850de134792726110caedc202a57c7385b29695e37ad0b1aa8b60dd
MD5 753f4c25e25a89b70cd024af32b4d240
BLAKE2b-256 82595f5684ed23e7de436fd136c86ec567a49f51ff304129e4ccc2785f78cabf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 ef0c2ed8fdbd78af4819f5e0a5819001036bf3b93dd59f8dbf084d42fc5a924f
MD5 a78cc6a5aac6a95ab37eff43072e4fb0
BLAKE2b-256 239bb4f06d444f0f6764cf0110eb32ea94f6a3b7f1ad9c6ecb40d50015090949

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2b5cf40382e579643771ff9ce955b1b4ffef2ce21204a71a35c4e0f088c7ac2f
MD5 1ab755c845156d0a93e13886820c99fc
BLAKE2b-256 80e8e459535874cfcfc228487c61ed4b8ba730034ab4964355d891a6b7fb6f80

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 88a8f393514931daaabcaddfea357feb654c9f7f8cf880bb28c2b90f133b5751
MD5 84d695fc2328f0bc43537d50b475525f
BLAKE2b-256 197555b7bcb08765d95834f41a2dd0d2cb0be3405a91969e80fbc2e5bbf83e42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 6cc30facb78625c639f91e670c5fbfe1828242209f46512b53978ad458d483cf
MD5 092899ed56b2918fa2cb8c95473973fe
BLAKE2b-256 f83bbb8a97d7be92e2ce86a23a679d4c68fd94c08cc96d0a0d95f7267890f97b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0c06dc5c3e37baf8c179c02a35f0329ba36babaa379e3f38e3eeef30e7ba6df8
MD5 5a14e0cb512745e74260910853fd13d7
BLAKE2b-256 86ef0c1017ae9145cc209775c7ee840a412de8f178b8e93426021cd20803d16f

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d757ab0da1de925e336ff29525771c3a36db8d0b14f651b85a8db405282f2a8b
MD5 b7b617e73a1f115531f96af4f1c8aa68
BLAKE2b-256 eeddec95c6709ff4cec2d1caec015b84d78c1d73f2ab80a5c04ea42dacd7ed17

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3d015c286f412d0edbc57f01c65c08343d1406412643b77e420103c960c2b9ce
MD5 d54b0a4f8f946b261537995ad73c3fd0
BLAKE2b-256 691f8f2cc7978d89808747ae5ee424809c7a221a1959749a28d30f41d8320965

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 116243b67d37b709969d157a52bc90dfb8ff975a5d248157591b4dab389502af
MD5 09ede034b24e1064a7cf85c47288ae84
BLAKE2b-256 b8bc61adf790e3e95b1d57e126de7910bc75481805210c64740413b85d6aeba1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 3670b29e4425773b634c4d57612c06615b24532c5f16b21c5194981e5f6d6e29
MD5 963a7324e4818abbbdff6fc2d979e2f3
BLAKE2b-256 9b53455ed29862f0a2f42dc3e82b964fb859c036d8e92db5bbc69b3d83a23bf1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 9a4b21c06602a6a5b3949327dd633827b929b1ce39598b7143a0196e6782b5db
MD5 095e918d396ee2ee124d018aa8167326
BLAKE2b-256 82b314c96e51d53203635abf3b781d758290a17353fc1a4f793ded3df28e57e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 77648465a66caf7ffa3b8fea4f2e5560441751d2d34bb7d603a22f2d0d6d9a31
MD5 f4845942ccebb8507212f79487c66e69
BLAKE2b-256 f7e5ba7750644d3e9543885c7d3468426c9bfb2c9387060325b25f6af449fbbb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.6-cp38-cp38-win32.whl
  • Upload date:
  • Size: 68.4 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.6-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 0be4b9189a986de4d6e4349d9d587a5320b5a3c53a80072924cd0019d4f3d5f0
MD5 411734b97d5c57f5f7ad218b914352fb
BLAKE2b-256 0356dc418d0058d08c458b39258e27fed08ccf753e8a948c6c6dfc8015cbb3e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9a550d7f2796bec40a0ecdf54a198ec20b8c919e68e3706b2a5239eec62552ac
MD5 fd626abc5f9a4b1fcf6fdb34c9adebab
BLAKE2b-256 6219c8127851b1ff0daad9308effb28d0a6dd53ff13b7e2e97930e54c58031a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 42bec620875721c413767507645d0b23079980776e8ab2eb38dd532d88e2b106
MD5 b2e48e3e1b73a131aba49c531cf5374e
BLAKE2b-256 f9b01ec9c0a3f1722cee6a1c713b4f1ebcfeaaffd0ae566e031a1e4b9b532113

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 5d7395b37e60701d22e9ad487da6af1500fe435fa72c8c93526951a5423cb7f7
MD5 ef551fbcf8709286845080532e83f671
BLAKE2b-256 cb5a360e95e52ebbae45d55a9711aad32c24c3c234121c0edb070081b74a5f9d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 7adae992576821b993a83ca0ddb31bb20b86559a4f39d06b7950e76cbfdb94dc
MD5 69284bd1b7e5a51c20542544f96bf8ab
BLAKE2b-256 ea3314826c6850d92f6d8b1ca39d74ed58dbde1de1dc8f6641225b57a3fe89e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 c61c65079bc0a070337a900a5bf8a1506a5def561649f8ef81f0ef5a5e9122cf
MD5 3ae33edbdb1cc710d853df0127b31ea4
BLAKE2b-256 eddc0bbfeaa8c7fb7ba53afcd588d9f8947d6484f42f6b719946b4d4adef3a4a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b7ebd4fa9c4bca48b0d8ce10c6f3a97d80e72c02a22cd28e21346c0ce07b4fdc
MD5 7fb3aed1a0fa4f49d3445bb4020038a6
BLAKE2b-256 e60f958e59d19589d6606da26d99627a576ef90176d7d0cb4392038f560c869f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 5a778c19fc6f168f090d8abf3134cba9a3b274ba828c36ff3c480fd4db00269f
MD5 987b8ddd3a659754d54534b7725b5533
BLAKE2b-256 97ade26e2b1cc1f81dcf215d95a141500986054ce7e8187d921cd6ab8fce66d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 73ef3418a82ce435d5ae0cbcfe7ad4834ffcbe90301910cfa110396be72e75bd
MD5 48a7732a7565ab372814fc51f0a352c9
BLAKE2b-256 bd55312edb52c65de550a2da2e63e48b4a632a075e0ec7a17a6e3360f80e6992

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 641aa1cd00204aeac71dd5d0490485e99ce3e3e48dbdff9638292fa6f8ff7e9b
MD5 6d07c6d1e9f44235c95bc46c8fda0b8b
BLAKE2b-256 e51531ad2968e0c9586daa58a43c8d1b9800e443c59cde355c7373b623d84d24

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 660d355868df5e3edc425d036c65057999e78541d389085bfb23803af6b18f69
MD5 a5b63f427f83e7ecd2c58e678232950a
BLAKE2b-256 cb5c0366d72dc4080ec4660b836a73728908b863a09fa92664d5f96e066e584e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 db25868e7a944ada5a857f5b55fbe1fc79e0e4f3a76c9cd042b7d5b0a381ceba
MD5 49b05071466a5841df1e43dac9ec5f3c
BLAKE2b-256 85a429f80ee7d15a77c6a8163cb514ae98663fcfe03422ca8ce28ae0c75cc533

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 45ea45a51b6181f82b575596ec039528f16e5be382d944829f8fc3b124f61710
MD5 0e89679af1b4f3e9f7a9e771d07f92ec
BLAKE2b-256 b3c1be4b726ede01668bf38006438598adf2a707b835041a9f33aff22b5b51b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 0c53a57e30a38aace092933f70e9426ae225b9f4c61f507103fc271f0a128000
MD5 b6ec413abaf99f303d435636d0e084dc
BLAKE2b-256 95c89e2d218797c2f59987df74903f8a2bbc784113e5dcb6e1c3a81eb759625c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 0edf15980f4d0d4e32c85b700183ac1b71b3920f15b63ff9cc21cb1da115d269
MD5 6bc800209dbb112534252ed547822f49
BLAKE2b-256 2d58e55397f71ef6760208865f6f31ec9740093c7f2c612e106e6755216e1742

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 2b58935dc273b875b5b40e4adb64382adc88631a16f82efc93cf11c8b46899a9
MD5 52cfcd6b75a9cc040de3c288694db3ef
BLAKE2b-256 df0cf2b98cdb2e0a9b5e75a383efd57e01c4ecbffeda80204404f192da899528

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.6-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 68.3 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.6-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 4ee9b4e8d89f12fbb4ad9133bed476603a80f2e468977b11766d288c5bd9755c
MD5 5a353fcfa347948a27bfdce030eb7a8d
BLAKE2b-256 6f66fe3ce15ceeade8a9cc35802bf69890e11be93cf255ed849cd1814db459a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 37570a9117889fe5db9a9c0d946f293d27dcc0f772fe4f5f2ffa566218efc79d
MD5 e83f5d95e3abbf06ca1974a103bda6f6
BLAKE2b-256 1d217c1a474ce3de908dbcf5248bd36daae5ed947f59abf5ea01f9076a711bd9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 6d63d31b90c64d432593d5176d09cc83d7ba675f167554dc8462776c3755965f
MD5 1937a90136dba9424c1095908cb1c119
BLAKE2b-256 c9a76dc89f2a4208d162d62c268f9e23940e83da1006e8537c0e75222ef4d99e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 28f732f14ecfc35e57a3b680c1eaad1255eb3ee0a1bc3033346d7f24ae5c07fc
MD5 69f7a84bef619a8452961de3fb8c3def
BLAKE2b-256 0d2408607cc40d53db5a9596dfe891586aa7ada3ad1757cd2a837534fe2e3e88

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1746cea70b30b02527063f835b90e5bfb983f5bc09c2a700d427aea1746584f1
MD5 8a8c345dc5a5e3bd5298bcf08bb05af0
BLAKE2b-256 9c1303fa4ab64d11d87d543e7ae377ce1c3fefb7bf77375356488d4888bc3a3a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 2e050ffd13085115aa677e26d3e6814acc90ff4b5e7524c136893c045253277b
MD5 bda7a25393756f371ac5dffe5af306a5
BLAKE2b-256 e604c2d5d2fc65f2944e0663febc3b9dadbb3daf74c195655866c1e30ad604a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 249392d1fc72d7fff62693717f01e853eb0fb0846cc975093f523e570ef5a3b9
MD5 16cd612ef0e2dae3a4a8e3b1947f1e3b
BLAKE2b-256 5d82a8eb045240da858db97860c592c2a043138bc97830349a915ba1e085f53a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 013a728be1548dfc6dc969d9c1e9cf682d8113504001f5fe54665a67a12aa1e5
MD5 5041254525a3e8f8a907296d661e3c6a
BLAKE2b-256 fc8480b9a6f209c90403e2c2d53f9965d5086b02df5d498f8de7f177ad2b96b0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 87413e238f23309f37413ee53b7c59809140a55fdb905a55933d4c58bd73ffaf
MD5 64565372ae46e1cd22728e0ba59cdbe4
BLAKE2b-256 073a182dd90b7e408894b1718dfc43070054d9cb986faf0e3b24ce8e608bbb34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 df28a2bac6ff2b81beb032dcd1323ad240070d441b8fcbd3fb421bc545907ab3
MD5 542eecfc42e98fe3632712a98ca830b7
BLAKE2b-256 5807c957b63e6f0315614e30d633a070a82fc97e04cde2827686557a4124a130

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 25b4476c8bd5bc2a39cbf8aa33030145504e93d2104ab8f67801be9caf56c95f
MD5 c3ce3c433a9b684df8e0619db749d72c
BLAKE2b-256 36fd0c40346a87efa9221a79c91d433ab060d26b8b93e4d2faf0c0735e351215

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6befa865b9306478c1debb295052c2af0bd84d5cd5c5658a931da8d46cd88e41
MD5 bc2e9ba5b6d865c8fd348c5e23289e09
BLAKE2b-256 b9c66f9d0f795904d6336034b2c771d750f7de2c5c03871b7ed3e9c15f56e3a7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 2ba0ed3c00d4e41015726ab473b91dc44fe7b12ef2b65c4104921a910887113c
MD5 7845d1b4765b941f62e8af67a49aeea9
BLAKE2b-256 80f97ce6e459a084f16626528b5efba8fa622c0c70c4660e27b4576a66994935

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 9a8cb52fc82499f971cbdc590437a109ce14092f328e744d43728e24197d1ca3
MD5 ebb51553cc80c5249c3410ce6a9cadb9
BLAKE2b-256 a38a1500b844526acdb1b7e2162e072cb2ab9cd3590459d09a52652c6b3db1d7

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.6-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 68.3 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.6-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 e6f4e6fd57114e3f96a2e3ede22388245b68b65fc4e7215db70a6cc4e2edaa6c
MD5 d1b694b922e898fe881f9fc30703ae86
BLAKE2b-256 655e8cfcafb486d70b05f59bb949e4383f16285696ffb4836e01cd3999e88c47

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 087a80089f9fad13d85a5b5bb41725a1565c38b6de782da10730213a387f14f1
MD5 cb92916b16e9c0b5e94c95a3d6de0d68
BLAKE2b-256 d97d65b484e54edc8ca29b6d53fcb1e2db327bb1d7c22207d08f736a8eb51f0d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 1f815ef0960c77ed53af41dedbb9f3daef2f3c0df09b2e53e9296dc2fa81d6c5
MD5 c7d5d39546781ef3be8d5d2ca5e334a1
BLAKE2b-256 504f92e42682ab47b4993446f00d2568e7c1def91e9b014027ec8b8c1c3cbd29

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 e1c3ce5b459dc802ce3069b6aebb25f0d86e8f9db6a0c89714f65bf33589d5a2
MD5 8d6ea6689b3a9293c8082de7a3b9c7b7
BLAKE2b-256 b82cc668d3ef0bcf03099ff354b2bf991bc6136d5a3710758e705acde6f24592

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 f3c20e2f434db5b558f3a1ecef3a2908a6d57d97fff58a22f76c4538424975e4
MD5 40776cb13cee6228b4e6cfa4926483df
BLAKE2b-256 8e060224629fbb773a53de66057b23ebf988ccb9d22fa71e2a6865d1a7cc48f4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 31514350c68e560714511e6f36bf6d25e1877d85019c88143c8e1751397259f7
MD5 740a4aa82c820b7feebfaaf46272f0bf
BLAKE2b-256 68c2372f096e860b22f57bf8e45c166eb7c415695334964a401d3f79369805c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 f49b60a159b743a0d97eb83665d00000a35fad0ab708cf6ccaff87d70572b96d
MD5 329154e4cacafb12833eb9f2efaf9196
BLAKE2b-256 f1293a36741986119e575125b9e8087002cb830e81e84f2279e3e5a8b12a48aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 b1ea1170d47d83315ec95fac3aa26db43355927da9fdf74c46634a5d2960888b
MD5 2a4796d262f97fa9bad48b6b43914db0
BLAKE2b-256 c583f63ccd00474b0de7241f58ced8ae7150cc5ec6fc1a92b0e61278b0e82fca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 e461a2f34f5d1e04c6506869ad25a4f8b9555f2bd70454f0611b05dcef350e42
MD5 e00b22e40c5d8342e3dcbb02c4af30d4
BLAKE2b-256 ac15afc68fd2701acd4b8ec34d0425a5c23155ae52dce6ab8f4afd2fcae70158

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 310739babaac6eb1a7dd394f632def67724e4097f66b291a001be6894e7d1c80
MD5 2087eec280712049eb469f2210b7d281
BLAKE2b-256 005640161de5c77af5d4fd4c934183ae32013332f71b824cb70862eb99d80a5b

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8bfa3a505b765e9f663d0b757d23b942d548284b97fba564002511b1168abb26
MD5 e21d6bc2937ed6cbad1bd3bab3d121f9
BLAKE2b-256 70edcc56325412e2f113fe4bda41b3d63dafb80a49155fd22ea98ba6ab74f270

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 588bb19ac32b2586842aaed8287a764d115fa777c4e7907f06d1eba1d833e367
MD5 dc05d12a0210a2c9c99d335b45541dd5
BLAKE2b-256 ec330f50949617cbddf75d981110cc5fc2c6d38e78a553b100015f66a9f609a3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.6-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 14f2422e9393d608cbc04b3377de18cbc0bf796f66ea142e76fb63be65af7fb1
MD5 61e620b25c3e295f0168d2366607e734
BLAKE2b-256 87130789d73911b9a05b78927a1c18945779e89fb53950f9e63caf0fd9e9fe10

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