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.5.tar.gz (183.0 kB view details)

Uploaded Source

Built Distributions

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

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

stringzilla-3.10.5-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.5-cp312-cp312-musllinux_1_2_s390x.whl (205.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-cp312-cp312-macosx_11_0_arm64.whl (80.0 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.10.5-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.5-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.5-cp311-cp311-win_arm64.whl (67.2 kB view details)

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

stringzilla-3.10.5-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.5-cp311-cp311-musllinux_1_2_s390x.whl (204.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-cp311-cp311-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.10.5-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.5-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.5-cp310-cp310-win_arm64.whl (67.2 kB view details)

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.10.5-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.5-cp310-cp310-musllinux_1_2_s390x.whl (201.4 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl (220.7 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-cp310-cp310-macosx_11_0_arm64.whl (79.9 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.10.5-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.5-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.5-cp39-cp39-win_arm64.whl (67.3 kB view details)

Uploaded CPython 3.9 Windows ARM64

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

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

stringzilla-3.10.5-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.5-cp39-cp39-musllinux_1_2_s390x.whl (200.2 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-cp39-cp39-macosx_11_0_arm64.whl (79.8 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.10.5-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.5-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.5-cp38-cp38-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

stringzilla-3.10.5-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.5-cp38-cp38-musllinux_1_2_s390x.whl (198.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-cp38-cp38-macosx_11_0_arm64.whl (79.8 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.10.5-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.5-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.5-cp37-cp37m-win_amd64.whl (79.0 kB view details)

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

stringzilla-3.10.5-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.5-cp37-cp37m-musllinux_1_2_s390x.whl (197.5 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

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

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.10.5-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.5-cp36-cp36m-musllinux_1_2_s390x.whl (197.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.10.5-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.5-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.5-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.5-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.5-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.5-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.5.tar.gz.

File metadata

  • Download URL: stringzilla-3.10.5.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.5.tar.gz
Algorithm Hash digest
SHA256 9fe1f6a39126faafbc4d92e90b5b65549e7d7d86fe24ebbcfeb27bafed976ffb
MD5 1d7af427eca6d71808b0beeb679c99d4
BLAKE2b-256 b8090710864b5746b15f05a69f9c3bb2926b6f837ab2945f9585bdea59b9930f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 e58347737daa8c0994f9e15a5936bdae45c1ff4757e27c5e9269c5be7b2f941d
MD5 000e7c22bac3a8f043939e0e5800879b
BLAKE2b-256 782aaeb7b57dee46aaf46f666fd753b7c7f220a896306bddb9ceb9031e6c1f85

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 3ad7efbc203618983d563646ef8180e9bea051a9715be04c778198da26e54798
MD5 8d1ff520ff576890734881472944588a
BLAKE2b-256 3ec8bbd0ae7c3551582c7e11873918e70aa5276c108f7ae6438c74414fd90576

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 8891f9651c7c60a103599f542f34f4f40d93186c35dcc47779a64f81f5843f46
MD5 934c15196005e45a9912a8e6c3848e15
BLAKE2b-256 2ab84137b90fb7087987ae1d6b6709283cae60f17a49e9ec59b7455a64d84045

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 63f6ac79e4edcba38c34e66f4a227a2a53a99a370eee3ded01b490c25f74b0f8
MD5 d263119be5620e81a9e48823890384ad
BLAKE2b-256 9a2a58373044eaf32ae96356a334a70055491af8c421f79a0ce730b7118200ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 9f24a966702aa5f2a6a74a442984bb7965f5cd041a4c25e1e05404be08e2738d
MD5 cacfbb2d676dae4298e83c91d74ca5d3
BLAKE2b-256 188312c52fe96382f0e56cb6f0e2033c58296170fa8ab553958872df22ad23ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 017a13c6df4e73664f2139d0214ea2f66da6b55f1819b326e0f3ab910f3db712
MD5 5ca3ab27a781bd52238f402553b3ca52
BLAKE2b-256 9bd1b95e7a08ad58dcfc791ec18ec631e3a2d7cb0db7452c8941519fcdfc60e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 7ebb6768970da6cdbdf5f34847247061b17bad9c53e9360c1ebb7ab2735223f9
MD5 3f971b54140aa83b12781e081e6d1fe3
BLAKE2b-256 20d620eaa2cc6861e6c7425be069e4b5eb7d3cf29038e38f8a307aa36006f698

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 4ffc0b70f726a6056d3c3c8c09dcae528f07bcaca6467fc6b3ec27657f0ca61b
MD5 c0b7784fd38283b06a71d0f3107c0b2b
BLAKE2b-256 d73312277f836dcef24e51ffca99a7d0c781f6e55e538529514b7c95070bfe28

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0cbce298c37fc1114ce6fb736757adaa785ab115563d90f5047092d2c1d8db5a
MD5 34e47a87e144e101b026a02da4e3db6a
BLAKE2b-256 908b2cc6647be63ccc1b0756eb13bb195b6668e1b1588adbe10fa16bc268a0de

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 811976467a0fda15036eed863bdbc300880daf522bd638a0b6e8ac5ca924cb8d
MD5 39bc6450a9e3bbe28595dec5419c3244
BLAKE2b-256 714dfc383bb1cf4ea520202fbe0ca86caa85eb3547288b9b4637167187dd077e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 c1233b5f072d554cce0abb3be53f76f0badbd577f30b118e0ae94ef7c6818ed6
MD5 d40386071a63f86fd71a676634ac561d
BLAKE2b-256 95a6c457e2a0e05e5260f452a89f1e95c6a0df5d5fb516c1b435d8ddc40c5ee3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9fc7b084624c9ac8626e04529b455b7419a58f2eb7b982ac8801eee730264417
MD5 fd48ecadaeb4b4d0f8d32311de9d5b9f
BLAKE2b-256 cd50aebc1563d54e25af91d0145cc02a5dd71c6d4e2fe3dc48a064482d603d55

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6f0bb284996f28c700b9e6f0acc61ea7c37954e24547fc2972d2ae4c485243e6
MD5 b63c89f9aa5bb43fda8a6c56fb539597
BLAKE2b-256 7652abe6e9e2d09427111afe52011dbd7fc136771a53d65895a78b2031e1135c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ae010adcf843f10a05da589ee3e7311790041b00cb2b0e5fd0addf66ad817105
MD5 e41d31f0c5fc2e8c35a033dcff023d72
BLAKE2b-256 360c9b40a041864b3a398d9c779a513136d2a3abccee1b1e69bf39adf5767773

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8e2a77d53e4cfa7fa8238cacbdda2d4b4629d24d05a3818f34a72851102cd6ab
MD5 68bdc2c951fb0ef9d0a722b73829a82f
BLAKE2b-256 9ca07f59547f7927f434ef4ef2c4bfdc8193f5a9ba678344e607569a93428ab9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 677464a32181c303e647683722bcea8eabaad2df05b8eb892e3c8e173b118cff
MD5 f9c389607a2643234c42c1c310e9457f
BLAKE2b-256 ac9daceb9dca7c4611ff5a2b20b3aff8bc2cf659305a458bef902ec6e7b75db4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 e89343bed0ea9078a7bf4da3965cb54ef8c5fe94798b5eae34f4806c36d0a341
MD5 3205901152b82905542ae7622a44c183
BLAKE2b-256 92276fb7f6ac6e67dcb4191e2bf77f25471018a27167e93f4c28b706383fef2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 edabb32dc1e92a29dbd94999775a7d5114a1a5057b3d0a5d24fc286e4e67f2b4
MD5 6f8ad3681c590b626356016de82a8b3a
BLAKE2b-256 dbf41990fb5af7e5fcf076a9277977cdc530dc31633aae82e9ceeb6119c33cee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e18117a1f8cb082a99b961474f71fc68d83d45feee2f1e5a5e7c7572c520ef0f
MD5 8184115dd7cf31f5b3c7870a0bb365c2
BLAKE2b-256 568f82318b2614dc4e2e4746004f60baf47129cd215f352232fa388c3b2e0cb5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 8597385f71c0deb8c58594c4e69bbd3a6bcf7c40e86c6ab6ed37ee7a5684d954
MD5 03026e135d8ba7f96612dcb00a399eae
BLAKE2b-256 cdb614f3bbc45f0a92099896533ee0c01046321a3a416c7cedf0546d072562b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 24c6b4e62fe2b639b9ead2d52b0c61df3489d56765af93a4edb483f246a971c2
MD5 8273fda8ea664dada25f68ba7d37844b
BLAKE2b-256 98bd4c47fd5e3749f89423f80220d25c089d636bb5beca1794315c998c6925e0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 52f4175d6535cf5e0246fb94f416a96ab3b2beff2c924f137a41ae667ab85722
MD5 12ea21ede36422ef4bd693a60d55c152
BLAKE2b-256 f10ba541a7202a5573648104b39cf5d89d2f6ad0c0d2df3ea80f913945ce4ea3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 9529bad2ff8071b4dfc76a9dc839a43beefc0dd3cda72ecb9bc0260d47af17c8
MD5 1d3dba9b2c42780f6badc0e048153808
BLAKE2b-256 376fc5e75bf79ad817f5b1786e29bb5cf22380dfdcaef443d64646be4c0a28ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 2d84d7e9bc997edc993afef83e5380a67d881b73936a187120f9d9a8474a1994
MD5 7bedcf825bb82bad0ad7c66ff864aad4
BLAKE2b-256 7231fbdd5333b545656f4540945b74217dfc934485fa714c5937dc6e87107959

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 93584f93d329eb7161facc5fe05591facc438f71b1e6e733903569b4fa93ac3f
MD5 5d61641c8a498acdba183575872f112b
BLAKE2b-256 3a0d260853ce9f47d38da1685969456403bc13d4c4565180147a9224068fe608

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 23666be391729471ceae56659e8b795c55613e2197c5751814b89f77145ecf45
MD5 aec29a81d2209f3bfdfc6676ecc563c1
BLAKE2b-256 121ab9aa2ee1bb2267c4662302ccca7a1821902ceb2e4078b3e33efbe657fcc5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 1f434b351fbddac0b4c5ccab09be43c7fdbf6f422f8f22546ce90103cbce783f
MD5 753570d457220a4d25e06b6962fbabf1
BLAKE2b-256 b674dfd2f4ea95e5179d9019d79a6a81da9e35d59f880e1e2bbc4c81ad3387f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 4c498f37baebec25ef916eda6c908eef7ba0deb727c1a6e438f2893dd1513906
MD5 247d425272887c7b7723eaf1f07a18a9
BLAKE2b-256 b7f025a84612f83f49bba165ddc1736e53858379cad92921aaa4a966c78126c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 da94583337bd491b521dc9c66a3724124ad0be78f6882f75a29874e39a694826
MD5 99d11b7b39174913ca2e82a0652e9f29
BLAKE2b-256 630fa885da896157d1aa9a0b7af9ec705647838f19867e845c004b4eded9d164

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a01c0d6135838e0809dc56fbcf5c6053351ef6b4f1efd04a91812724481a9442
MD5 7354170c5697060e3c1440d3bd77666a
BLAKE2b-256 75c579d4d955432a257b1c185a035d95bd17a1bfd71fa3d6e4e5164d115f8c6a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7ca03f44342cd1b8fd78205d2a5ccfc8efef426735ed8e537136ff2ad9ebbfef
MD5 c058c8221945448ce2ee22fb463e04c4
BLAKE2b-256 8eee643d50b069341f0c9a9c1b97feaf83cd05004273ad17b45bd7061dde6181

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 06978d47ec3e01128a55490912c6c46b383fbfb19d1fbcd60e36b78567b7a7e4
MD5 1e0e4293857917afad9956a285d1b08f
BLAKE2b-256 aa838993203e5cfef191d90ac0bcc6c7d2fb5ae168cb46977d0f6a3874c15713

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 173511d71d949a78585e0700f077446d5a6a405e9593f468f61afc153dc59956
MD5 cf28e22845b845fea95851dee0ed895a
BLAKE2b-256 734c14735f5cd7f7d0342ce48bc39117af1e747f09fd65784e315ee2f20d0922

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 d898b6149b0656204d2dc02e9faf9596eb7812f438dd0c31c961f5d637a8de3d
MD5 bbc6c27f668dff7959e7c91aa7968739
BLAKE2b-256 4be29e52f1b631c6e0302bc4c4757d84cf4b02079888bd72a892bd66aa04f772

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 3f2197429586b9390393f091fdf1b8394f661f444f772ab2334680b6def4f934
MD5 856bbe1cb9853103021eeba7753659b5
BLAKE2b-256 ecd88104d7d9d019bc8428e2a9fd7eb1c2034484095d68c7135e6fb3888eb27b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 74cb16fc825d4431b4d8ddc9d94410d96c1e02cb39386a40118f5e9cbe585245
MD5 8fbba11cf79a0c52b9728325fd199c5e
BLAKE2b-256 83d87eab1ed673d07ac440fd08904f9628c94ff355fe3005e460b59a042beae1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 f6afdedc846acf964d3a77d64004d745357a93143b817d1bcac9d02e477580f4
MD5 c394bcba5407d534277b878da1f3b7ea
BLAKE2b-256 bf1b884699f48d4672a97aea3298f209e4394f49db1d24b3cb0afeb69c21fe4a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 18b0fdd5a946c2ff08729d9354ce7f9087066982f49688ac1190340bf884ba10
MD5 8240c27953956819b6611fae8f9b34e4
BLAKE2b-256 04cbb7703188fddc402fcaaefcc35abd7be0bb4f04e64115177c16a4bc091d7b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 d1f216144ccb3d7c1c4b3cc75ebf5d1f74f196c3d76ec063634bfc3a44f79592
MD5 3e1f549178a90624c605c23edcae56df
BLAKE2b-256 e300aecfd2304df9cc07d495f9e183712d30dd26ee83fe2891d69694c48999c1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 22f90ee8cd9a9e063debb0f0735a96b782e047f33cd1afd8819da858688ea0e8
MD5 5b431a79f836f33ca88c45eba7c8f73e
BLAKE2b-256 29e60d3046ebe07aaefb0445d32d04d831e43ae5505263110c43090e816ed83a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 601287a6a496e3214217bd52ab73a0405cb26b40d9d6681717475c3611d1f495
MD5 a82c45d715dea31accce1d4cc0414421
BLAKE2b-256 f24b6ace1c330c5b54878276f6c4e73728eac70ba0aabf14f6d5d9ed7a27f58d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b4e334ad2f16e0609a811df16593f438743b0f0bb06c2b05f73d844439893a71
MD5 cb6df32498aa689e3d94531496c7529e
BLAKE2b-256 c23209fa68fe11cc66d53be25d6afc3192a8ab7dbb0b7cca1c29997882ab2771

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 839751ae849c2c852a4c8d79bb919897a528969f8984d9c6372defefa8ea616b
MD5 b94603d952bffe85fdaf3ef4c441e97d
BLAKE2b-256 4619dd6b8e972506893a6cc40a57cab213925279e6e2db3e8d696c2a39a14107

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 daf54c171bec98d5ea59f70331d8d4cee6a72a91a8a0a201312754a3f2aa6bbc
MD5 acb0d7e2b80875d3acb71b567c9bb609
BLAKE2b-256 e3e4563dd118501482c2a65a17120045d3554779c152d654b655210ba83a726a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 4ff68e9f85234c9124d41dd27fc94069c4a546f26155213f25cf59c9a552bcdd
MD5 126ea7d41a66f750613210642ae7b81d
BLAKE2b-256 19a60a92c9083502d7ebc519d77298fd84a330a6985ba34517375530a4babb8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 09a675ebe5fc18138e66bfb14130bffbdf9dff2c6429988230b9a6c43d647c2f
MD5 dd87842ed0aae77f2c17b666c449ad3d
BLAKE2b-256 1df9b08794afb4b06f2f21eb110d89ec900fd76ac1dda02fbe9724fe540b0858

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c313108566dcbb61d2a3ed1fd824877c32390d84dddfa6c3c7ca99cabbdee64e
MD5 8684a205575dcfba3eee189b7c5e17a6
BLAKE2b-256 c11b5b0e7e0ae43e4051ac0f82da264c9e0763658cb2941d52a5d10c6ebda0d2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 5230eb6765ebbc4e7472b2d7bde84ead895fb8fcfb862cec8b5fdf3709c94553
MD5 8a0006acbcff20bd6bb69e0ed3b81703
BLAKE2b-256 92676555fb8cd52feffb511c1c3ff91e38d7eb05e47f3e1bf8b4437a053a8e38

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7cd8a96460421354a8c4445682f8b4586c04fb9e593aaa42503d7c8b0797222e
MD5 c128e5ae346abbe1897911c8e3844efb
BLAKE2b-256 872e1083974f0ad1ded3af71904ec995c235f6414664caebe37bbadc98a3bd2d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 d48fa0196b07fe25e5f5c907877c26af27bff07a1258fa87fd7ec2a611d138f3
MD5 f0fb063c7c94db5e7a66ede240d825bd
BLAKE2b-256 5fabeb7cbdda6e15b02e7a44cf19cbf7ec6dd996cc654897c791485724efa180

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 0faff79e6c7a4b6578ea179105f104d25af852d54d3087d00b44c5abb42b0880
MD5 1c2232640fe40e49e039ffb99ec2b074
BLAKE2b-256 3fca006b5990b15d3d1ff5b3a7c4a579220ca7a57b03b92772d3ccec084d3dfc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 18c0f10c259b709d78535f0245d74bcd935248b5db47f2bf659c3b52853e8f8d
MD5 6fd758f02683a03b4cfe3e052fc18211
BLAKE2b-256 9aca202d1e134ca86a1186951ea42de14b7a0f00890957ee1c53d8e991ed03af

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 57d0cc392888208fecdb12aad0f4fbecb5c99091490a5c2fc425c2445af97f59
MD5 ad38f5bed2d5cb76c94ee2988dcd1bb2
BLAKE2b-256 e3a5fb383ef48481e4053d391151635a315cf407e3b5c9e77f06daa17782be6f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.5-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.5-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 e426ba659137ade2b2e5d2dcf92fecbe5154377588ea82cf2184456c56934240
MD5 dc016ae12b44935b5aabe4c91b37bd4b
BLAKE2b-256 e31bf3722729091338bdb73ade4a56d89568a4fbbaa31c9d0abcf9ec969115a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ff821a03641e1c722d1bd70139a892b9a44f8e627f6f2f34a3f08a0aa062b349
MD5 1d3a7d8c7512685fb01f378f8439c033
BLAKE2b-256 17fc026ad07442bca7d56dbe6c1b1e9710fd684e42c4d70f558e8d829334eed7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 390c8f73a5d930d676b1be95a25b2e6daf327b6e51fcb444c21237bb12d74961
MD5 64d60348d57d115b5a63971a428ea68b
BLAKE2b-256 797b7eb2959c705cf09f99c3260903dccdbc02a7b41138e1a602030dce8053e7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 8197326fa99521c80bf93b3c9400a6ac9034ae4e3c0db0bb8173581a02593b25
MD5 b2a01131e3798da49477bf4725c77033
BLAKE2b-256 ea3a7b43b898bc522a774446fa401b86df12dbd762f23fc2386617551b797e1c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 e8563ebc8c84a5e8638181269b283a75c07fa55e80ad988a08e82bdd8ce85158
MD5 97391ae274c56570a58f9b22cc9d3dc0
BLAKE2b-256 8286a639f9bba3677bec786512d5b44d76194429d5522499c2f3141570b322a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 0386b65bf44cd72ddddc993c67a745fbcc61fe9ba0cf76fafa8f7e818e1289f2
MD5 6a2e4030142ababb6a5a8b6b18b721ae
BLAKE2b-256 2035639437d8924d0c7602372d95c84410007dc9ab4594184eeb3e9994f73078

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a98d305433c391e3a164973207f1cc599e5a294865065a88320d07a0f399d1e3
MD5 1b10313fda432b8c776dbde552645e05
BLAKE2b-256 9da6562f8845a666a97ebb37b6ad6cf87baea473b019e21e118781e4e74cc18a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a1ee14b05e631be09b3874bae8bba0236bb78067239315d3305c78631435f022
MD5 aac9a5418028152973f753bef787007e
BLAKE2b-256 b1843a4cea880016bc9e096e4761a9f0305d5c9a4e3af198c1edbc4c8c6aabb5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 39949ec3665bbae477eeed782c434737f27fd794984ea8021f75f809b37dd08c
MD5 bc3fc2cd60bf1b20105f5c01874b48d5
BLAKE2b-256 26777d4074c02d1b79ff0e50d96d7f73fb004d513e8de911ce2c6897c9c6b7b8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 74981b5bf32d67050940dd69c9cbfff3f10bd1ed8a2b76a3310dbbe609211f9a
MD5 1a595c0639530a25a90589e72c133cf7
BLAKE2b-256 e3e9247cb5df971abf6ad9be872863532872c5f7a9054540f3dfcdc7379783f0

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e962aeb9c58fd0a602b57448155abf5fb4df80002d3d522cf9cc4b94ad1a5709
MD5 b65b9f0e7805f333d04db955dc4161e8
BLAKE2b-256 22c42252896f9398f97a90c3dae4119871b707762af20fb10b594066b18ee404

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7aa391f456d74d6e32e7e216cb9ddbcef3a168cb33f97d1c49438ea70e9b4a47
MD5 764433b2458dc2ab424fd81bf7f939c1
BLAKE2b-256 0c1e800d962a995f11e64e4fd2e962c357895b8dcff15a5f57e8392b6a887de9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 181c14e281edeb034ab37dd3cba398402301b051e28609a4d00bf0575a393499
MD5 0d3ae9ff3034671f1207d2b86b9a18b6
BLAKE2b-256 4bb7bfcc524b4852ab8221d480bae71d1d1f983b6fda386844cc9ed0799b7749

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 0be53508615f4af7bca8b9db842e8f80cecf3351bf25321ea8af71904e3b92fb
MD5 a84f1e62fa3038cdc5e83741e5367c7e
BLAKE2b-256 df8fbb1ff67a0b09cf731fb020a668538fb9ef13c36dcdce2d985cd67a3535f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 b1b018ca8f876c43a072057ac86efae99b29af23e7ae03e25318eeaac5c58fbc
MD5 49b166d23e170328614b18946d3295a5
BLAKE2b-256 b7970462b0527be5cb761bf6d3b78c96d86917543a6f5706515fefa33b83cc03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 63ab84ab55c86763f14504d295ef9bf1c82f24f11d47ed6a5e77264fb71c9233
MD5 c363271bcbc0c681eeffb59517c0714a
BLAKE2b-256 7e57a224ee3de9c0990343881f8eff83657e795ec9c24fd0ff64a735eac2879f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.5-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.5-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 3c8ed1878645026c97227f6138bea4954f5f056f50c91ad6703a22cdbed0197a
MD5 0f1256d4934a57adc83da48d9310ca90
BLAKE2b-256 34d79a10c03af961c238617f56d84644711af8cb6fd4aa82c395cff8c15887d3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 304ce554e40650844265011ccb9d3726e36a6d7be366dc5bdecc4db748a01dc4
MD5 8e17580b723f5a5e14c01a3eb59210b7
BLAKE2b-256 01bb8c877e348f8885786a4a745cb10414651565b3d095711afb87ccb666f827

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e704391125316e79bb9ebf2a5be4ef5427ba893cd3b73e9405747f5f9f61e3e2
MD5 fd7bb4e40ccb510cf0444e500f14263f
BLAKE2b-256 2fa235d02a5f0a6bfc5f3632997ce12a8f83653dfaf5c9fb0d18ce7c50eb41ab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 3c9b6c14be15855320b029b23bb20a8b0986b17b0e3de7ad92c92ebc6525483e
MD5 8306cb14eb5920e7a9a9576660953f22
BLAKE2b-256 233ddcbb72aefd34bf3aa95fc21681dd082c38209fbe111cb491071d9102e327

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ddd9553b15dfb69308a2c51ee908e19e7c201b608f381d1eb054af616bf66dc8
MD5 e2ea6b4d66e70eaba3703e09440a4c2d
BLAKE2b-256 021ab12ffcd8aa7f658a4d4dcd4d621a467e1a0ed6da77460b8c4d6ed10f76d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 0f232340b504a031a347972d99675cd76918e6fbdec6f090d95e35696f86ee57
MD5 94826241f3de9e16429f695a9efe1be4
BLAKE2b-256 3000f15fc9297d03c4e80facad30d5472fabe731756394ed4a8c7e1100ee182d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 5d671cabd1a38feda078cd7127f05191a6f47f95a1511a69ffc5434b4d010c42
MD5 055902c4b98168ebac13ebc8444608b2
BLAKE2b-256 18fbd4052b9b73aa8dc8bcb8342dd0aa6dcf5eee51417dd2d70f616af1c098ec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 e00c03b3728593640bbceb682b5f277c0028d505725e9fb71d536940a51d4b4a
MD5 23bbd0e84b948cf410e632e533f8fcff
BLAKE2b-256 256845d61885afed0a2ae763d65bf8c8c6391019cc13443007630ef04270fdd5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 159c5de51638f56e91303a63b4960274890e3bafdfcff511368148eb44791a2a
MD5 df5a2a18c9146e1f67c958aa1f6024e7
BLAKE2b-256 41e1fc3d8f6d6563476db51eda8bb381f8028adeb12b9993fe774fe1a734796f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 baeea8e879e5f1982c7e34c86410d42e99bb23f1869dd6040623e25adf0c6f71
MD5 6b6622752cc65847531ab5e9e73156b3
BLAKE2b-256 0cf8a3192eb3ab1c356cf4d5405cbad1f65c38806fbf78ddf43b011eca621036

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 739fa167de1b2c6c35ae47e6c6705b8c86a83738b208f0b1e5ff4548bc1a0dbc
MD5 d9509c1892ee3735b37b784e97f65497
BLAKE2b-256 68dfe9359348f42efb3b886d3fbf49b8e0557bafbf5e1cc3c6d7999768f7d85e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 fb9ede53b3eadaf61f53addf2f781335745c273cd8e32fe422e747e8c8d05be2
MD5 52186696ae8c5645b4fc3489181d9d1c
BLAKE2b-256 890d9e1f0ed3231c92a8c7b86d8d6d23181f15981444b616e0f1d8d22a8e8901

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bdaeda30b947cb00d08635092a049dc91219e94ee95506b99742941a73c5d8c4
MD5 3282a36195795e68ae1809ac68cc9945
BLAKE2b-256 1f93cb4703de3ae1accba5173bc61288c1caf0f91fed3f79b14997e7cfc386c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 1b4d190a88028f2aa5982b39e8111b6eac0fe8ddd50a0922d49f489d9b1666a6
MD5 88e3019d87b43a1ef93e3314109539e3
BLAKE2b-256 bd00d6b38676644541cfd456e59359964f327bb2be35d1e75ee497a9055fd517

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 417ef67849a5a4198ab526e2ede31f11ae9f78b8cd512eee8cb7e9a4c6f02558
MD5 4e038652d166355147a8b10c9d784adf
BLAKE2b-256 3f6422b50f9bcd0ce3a5364a1d5dc1caab406577d18709ef5d12a92a25584307

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 50e16ba80a21b39f7d091af268e7b5b198daf4125919289a41ecd9f2ccfc30df
MD5 59adb5c9858925bee25c0d4e21472a09
BLAKE2b-256 1a657c286f5b5e18f7742d1fd3dc4af5d077c748cc7ee0441c6e2f97527e1e7c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.5-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.5-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 9afd7751fc27f87992ec68c277d321963464ca095d21580cd9ed3f33deb0b0e9
MD5 e315b7079ba8990df1f3123c14550d8a
BLAKE2b-256 7326db4356b4c948394608a0ff0e8507160eb817876df9470a26957124e50ff9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 49307482402f18680facc741b567f1757db978ae9bfd96809174cba9fdc110fd
MD5 fc08db282f51df25c4194a2776ee322c
BLAKE2b-256 b2dcdb7bf4f04550454d07411ef57afe0763b22e42f202075431ae2861dd0205

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 6b95131d18aa953b4a8f0b7840a78b29b0b7a9c5c63b9aca8674514670ab8600
MD5 efff1eeb14ae3e5967caae8b8304f294
BLAKE2b-256 c1dbe73fad73412e32ea4e7b45cf6a8aff549a784f30c82165a76d38f366f384

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 08944d9470b6dbb7df770e4e31b4be9b869aad1454e711e8c257fb396ef9269e
MD5 02c13d569e24298bae958c4637f97a30
BLAKE2b-256 5393378b5be86f0897a4cb21e8aa70f8380c6cb53496700d1c865e3d224cc752

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 e4aed79ee766f1a1819eff9306a5f8370d85b0705f3f5cd8673298262f49232e
MD5 c814d3854c0afdd6d85463c39f4f6a9b
BLAKE2b-256 fc208643d915e3c6c740e10fae4e8d799212abe448c20452955df473ae556a83

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b6915048b24a8cce03d74087ee64a67b6383f88cc424f40f53ab6428c9b92adc
MD5 a098126d9386728b66986b3eea3bbe8c
BLAKE2b-256 8ed3f69bb36e5f7eb23ab5994ab15f2f48e2b315f81e7a479cc8cc36549770e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1e8335ffd0c3226944d9efd9976b8990c79c17f32391cb9c7cb7d9dcfcf9aa03
MD5 14c41ad4a3247a26ffcccd8ad17e5286
BLAKE2b-256 ce6be5c17ce7b74312bc694fcc094910d41aacfb85b360c8078da19e76835f9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 652ac0474a5bd9cb68725551921063a881728ac9acdf14e644a7e5331525b31b
MD5 01cd632499cc2e0bad0187c1b5eb22d5
BLAKE2b-256 a0053ffd32e145379d38c10e6ffc307f82670bdc814de1d0b56f881145cf631d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 4355257ec44e420f5fa64765fb9f9e15b59525764eefda28fcbf71216a918aad
MD5 0477db384edd7693d4990aa1b03ee74d
BLAKE2b-256 d96d3510979750c1739379505094370217264d68c665dc046ad7d6112ea4183e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8b5dd03f977baa426921e8026d9cf5f0c3570d93d48e112f8beadd3dfa73d3d0
MD5 09dd90a6dca3b06dcb05e09ac58b6405
BLAKE2b-256 a14a4d21e0b9bb061cadbb499bf6cd1c9718ee81384debc5ac31603d587ea70c

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f1aaf322b3ebf2b4918fa3f470e2b27f8e0f60d26066d20c9abde9fda5fc0cc5
MD5 eb4d7891081d536d6b4f0b42e13fc37d
BLAKE2b-256 504aa2b3a586fccc18ed135b5ace2a0be1b4eb34a328172ed48107b1d40e8bb7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 dc5ecc16c1b888184be1326ff4d43339cb01568a91fc0d6c05f70ec8d30ae6eb
MD5 bf71f655663b9939d3cbaef19d59ce7e
BLAKE2b-256 072b66915ad1a88adfae6236410b9740570988486a85664308d65228e5bb957e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 6627275eb5c3ffc7299e101c4a0a2d08618cbf19fdac5a9e764ead4dcc6cc34a
MD5 b50952797ae7fd9f58db0741dcdcb387
BLAKE2b-256 590d5d0130aa9efadf859c31150a91bfeb1210c185e77cd56c9d175c467e574c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 8bfea78944ff8949e7ba4ca807460c53acdf1a1e02af5b592a9c8d44180731a9
MD5 2a0ca6301c0dc88e4d918aa74eeed656
BLAKE2b-256 f73e296a84df1696444955c7302cb62238dee164d18d596bdc370ea032d32402

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.5-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.5-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 dad79e7e79d47fd063766d291ada81469647afd0054e88f2d5e2c433e6bca063
MD5 fb5cae95899fae5507c930e086c5247d
BLAKE2b-256 bc39b755ba64a52c7a8e7d442b6a9d828cad291e34d9711ea52d97f1c8ab1d3b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1d75967e92bd6f577ecba6e90135f89a98f38b6dbedc03063629ac25d5d8d902
MD5 df5141f69bd95e15ed0d95a71f2a769b
BLAKE2b-256 9ea88a92a14da9b4dad142bf21069d98525f7a06b5f4dc54b0caa0549b983b9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 6ed6616fe2ad6e9700bc5503e2241dbee7a2eda1ab5be24a3976fce3d5b46230
MD5 2aad52b138feda0d473de007f440dc76
BLAKE2b-256 34a505c20dcb215ad8ae34765a7410183040d1aab0344351397d4e9a9d728797

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 c094a7a85e3c247bc01bc27beb776b10a527a8d8a702edd34cca9d5fa43ba81f
MD5 3c94b079b688855a5960cb53d0511386
BLAKE2b-256 ed3b3a48b77e0a0cfed9a451a5c27df72d49e477a518966b2ab54318e0878c9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 1a076422e7ddc04ff91453137c300c5dff8aa12ca2b9c5afefb1cfea5c8094b2
MD5 23feb5080d1d923cace109dc3e348170
BLAKE2b-256 1b8fb7bbaebbd3d01a0b869305eac8b574cbcd01d08f625a3d026a6fa7742cb6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 d02d005d0cf76d8bba6c2aebcd647b98e404ea9e014ea48478ea65b470bf0516
MD5 90b27aea640d7a97336d91a6bf0ce5d1
BLAKE2b-256 ab5d95ea610b067f79c875c5d0bad858a26320c82afd64add837af0c2f5447fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 db41cd3bac41a66b26010a9eb5154a5918946b99685391122bb4292c8ea6ec89
MD5 00b4af385f0b7cf0858eb6f13f2db61a
BLAKE2b-256 71b89444ae09d18c5577483a282101e3f3602ccf08502d5eb7351ad39cc36d94

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 1226e2ff172c34e96450f59ae6b642e5ce33f80001c5bc161db6441ea5b8d9c9
MD5 6536ebe1be7ed3629a914da827ffbd8d
BLAKE2b-256 92e50e53b6820b4c39743db8e5724ed44662b3ba71e78f939bd0a0ee079db887

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 b6abfcc803b86153652585544f5c7c444351c150458ee6ce9dc84af0097c34a4
MD5 d527adc1eda546ad1dde931f2cbee8ac
BLAKE2b-256 cac9baa9b08ed90ffb9a86ff975e1373e19eddd4936f1a2a300d1c36e63adb87

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e627db846a2103f5a8351b90fe7120445ce571494013a0c26d3005b9fd6d4b2b
MD5 113ada0e40ca97d31031cf97d8c81923
BLAKE2b-256 148a14b358d08bbbcfefb218e1ccc44b7bfd9b897189e2697f920be91c835ee4

See more details on using hashes here.

File details

Details for the file stringzilla-3.10.5-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.5-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 115ce38058fbb319006d4529e4d269c23d7894e60b6d8d5850ae773ece75fae2
MD5 e4f4528034958b3ab3aed19acb6ea9ba
BLAKE2b-256 d462485e021e79719b07d3c0027b34279b916938c60016a5f7fee8870175f015

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 b3cb80eb4d42e14941b5eb57336dd19810093afba9c2e973e5e9e9b0e6686bb9
MD5 d7956c358fbdeec32df49784821a8f38
BLAKE2b-256 f51393935f9116fbae9fe35889932b98c2de1241bc0be9058ac3485b3dd3c12e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.5-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 fc9b4d9de1e34dd57d9fe5f88dfe67a4cb72dbef8a517ec6fadf0a04f49bbb44
MD5 2e9c5417c16e9d136a3eebb495daf018
BLAKE2b-256 33258d31439a2af065184787c321c6ca8f7f501142ec5f245187a5ac62d6f49f

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