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

Uploaded Source

Built Distributions

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

Uploaded CPython 3.12 Windows ARM64

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

Uploaded CPython 3.12 Windows x86-64

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

Uploaded CPython 3.12 Windows x86

stringzilla-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl (289.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

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

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.12 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl (223.4 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (295.6 kB view details)

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

stringzilla-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (203.1 kB view details)

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

stringzilla-3.10.4-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.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (227.9 kB view details)

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

stringzilla-3.10.4-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.4-cp312-cp312-macosx_11_0_arm64.whl (80.1 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

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

Uploaded CPython 3.11 Windows ARM64

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

Uploaded CPython 3.11 Windows x86-64

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

Uploaded CPython 3.11 Windows x86

stringzilla-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl (289.3 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.10.4-cp311-cp311-musllinux_1_2_s390x.whl (204.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp311-cp311-musllinux_1_2_i686.whl (211.0 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.11 musllinux: musl 1.2+ ARMv7l

stringzilla-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl (223.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (294.9 kB view details)

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

stringzilla-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (203.1 kB view details)

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

stringzilla-3.10.4-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.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (228.1 kB view details)

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

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

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.10.4-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.4-cp311-cp311-macosx_10_11_universal2.whl (121.3 kB view details)

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

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

Uploaded CPython 3.10 Windows ARM64

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

Uploaded CPython 3.10 Windows x86-64

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

Uploaded CPython 3.10 Windows x86

stringzilla-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl (286.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.10.4-cp310-cp310-musllinux_1_2_s390x.whl (201.3 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp310-cp310-musllinux_1_2_i686.whl (207.8 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (291.6 kB view details)

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

stringzilla-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (200.1 kB view details)

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

stringzilla-3.10.4-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.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (225.3 kB view details)

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

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

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.10.4-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.4-cp310-cp310-macosx_10_11_universal2.whl (121.3 kB view details)

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

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

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.10.4-cp39-cp39-win_amd64.whl (79.1 kB view details)

Uploaded CPython 3.9 Windows x86-64

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

Uploaded CPython 3.9 Windows x86

stringzilla-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl (284.7 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.10.4-cp39-cp39-musllinux_1_2_s390x.whl (200.1 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp39-cp39-musllinux_1_2_i686.whl (206.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (290.1 kB view details)

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

stringzilla-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (198.8 kB view details)

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

stringzilla-3.10.4-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.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (224.0 kB view details)

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

stringzilla-3.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (204.7 kB view details)

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

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

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.10.4-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.4-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.4-cp38-cp38-win_amd64.whl (79.1 kB view details)

Uploaded CPython 3.8 Windows x86-64

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

Uploaded CPython 3.8 Windows x86

stringzilla-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl (283.5 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

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

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp38-cp38-musllinux_1_2_i686.whl (205.5 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.10.4-cp38-cp38-musllinux_1_2_armv7l.whl (192.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (288.9 kB view details)

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

stringzilla-3.10.4-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.4-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.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (222.7 kB view details)

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

stringzilla-3.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (203.3 kB view details)

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

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

Uploaded CPython 3.8 macOS 11.0+ ARM64

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

Uploaded CPython 3.7m Windows x86-64

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

Uploaded CPython 3.7m Windows x86

stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_x86_64.whl (282.0 kB view details)

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

stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_s390x.whl (197.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_i686.whl (203.5 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_armv7l.whl (190.1 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (287.3 kB view details)

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

stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (195.9 kB view details)

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

stringzilla-3.10.4-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.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (220.4 kB view details)

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

stringzilla-3.10.4-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.4-cp37-cp37m-macosx_10_11_x86_64.whl (78.9 kB view details)

Uploaded CPython 3.7m macOS 10.11+ x86-64

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

Uploaded CPython 3.6m Windows x86-64

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

Uploaded CPython 3.6m Windows x86

stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_x86_64.whl (281.3 kB view details)

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

stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_s390x.whl (197.0 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_i686.whl (203.0 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (286.2 kB view details)

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

stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (195.0 kB view details)

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

stringzilla-3.10.4-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.4-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.4-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.4-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.4.tar.gz.

File metadata

  • Download URL: stringzilla-3.10.4.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.4.tar.gz
Algorithm Hash digest
SHA256 2073ce7f5b4c2ad59de0a049278aabe699e17d647cbcaad13c4aa86ebcbeaa7f
MD5 3e56e95814a8cdd5c5a00a69a026c8f9
BLAKE2b-256 4cbe8695601e43d3e4377ef2017059819e95bfc4e1fad25b097f878fe2600678

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 40ed71bdaa0e2cfe3aa594cf95eddb94c90718169c23df78463e7e700900c607
MD5 a6914331779f8692ac887654b462d91a
BLAKE2b-256 b962d1c059030dad9bbf3606f7832ffd66049c0ebb5fcf0b3b925ef02f2aa518

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0b865f00893ed7af48268a805ae59a9b9791c488f1b383bd77716a0c34f9efdf
MD5 ce19f4d4f8e1bec46ee8309b940e70db
BLAKE2b-256 5099492568504cb2a7e30ce8a7fa92b33fbc6547467cff181c415c3a36dcc6fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 4897a45d3ffeb7708cf256efdc8f43a4f7c5d7a2e91ac6be21fd01f9d773b48c
MD5 9cb9a6bce6c736f39fd28c1131c7dd2e
BLAKE2b-256 c414e44628b0e820a1cf06d8762cdcfd9206f1fd38608599b9cf454b7f01da36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f30ab4c96b9f52dc7b4b37f14053ec2f7d9cf2ab3b64aa44407b0f126a15c9ad
MD5 d24d12c3d22a044e0309d3680d7283fb
BLAKE2b-256 41e3e01735c1044be0da1fc5da6fa2b72c116f13c94a5ba21cbf49326c394d92

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e6ae55c83e243b8f68a984ecd25b657c8150de9f63643e183f5681c7f8ff1ee9
MD5 2d739096d6915231761ddea13ec80be3
BLAKE2b-256 0b688cd7c37208d5028e310b6a200f9771dbe31c1697597b4d115b945620f49f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 0153151b72182714ecc54c10917d78a44e6a12442942799f73aa36bcf032c242
MD5 21b88526f8364b7fbeaffd6069929b66
BLAKE2b-256 725f35508753e02b2cbf245e339dbc73f4682ef1ef5ce8465b01ec20c4bd0952

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 baa5cf0b09094186a73e4315f6a27c43abd9a1bc6ae597c4b6199f8dc153f902
MD5 2c4130d726761f15194d7d0e3552e4c7
BLAKE2b-256 645e7a5028c0c15d51adce072cede33fe2741a52212b25dc10586732be374c71

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 e23d0a0ac0d674a795b3533805d322be41abb076902654b7a5a9928dbeb55c4f
MD5 82e8816a6c5546debd41a8924b2c66d1
BLAKE2b-256 4f6f62091a02bf6324c24c31585819daa92f9495d1094768fa639b4cf46e60cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 96909ef81fb5082e3cf9b300a1fc6836974917ff7ea41dd30a37cd6f71626e5f
MD5 8d13d96f47025745cd09ce32ba52e97e
BLAKE2b-256 05105bea5aea85cc4931cbb41a50d538bbf2fe0c7fe3d83d8c4efdb9025900ee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c93c5c80e8fece028c72ee241a28c05598c0ac05dcddf496f1b9a22a9076f5fb
MD5 0774f0163723fae2408ee307b7849558
BLAKE2b-256 add8ab5300147d0d137e66eb24ca677d5ff6c5dc51c73584c14136f1c752cd62

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 1fb5e7e21772e073714565ccae8c3ce348ff462ee73870656b06717203f0e0d2
MD5 dac021b338ed7253f1b029f3d86dc8dc
BLAKE2b-256 f79ba766fcc5e1e3426c27ffa03001f70290fa96d20e486e378ab1ad5606f08b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 0e12fe5af4db1a720767814beab2426f42b7feb8b7859df927aa2656926da895
MD5 437bf9af7b4c959f81dc9d9b34c84811
BLAKE2b-256 a86c82763a0dd3a9a4cbb6545f64206adbf4d33b9a8386e8b2ea9a12076ce0c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d2de193334051e86e5f8c9951b349d62ca18616dc0fee878328109a16f61fe34
MD5 7f35438262c54c784e743bb966d649b2
BLAKE2b-256 31c1124491fa8a244d8db842d5cbca23cbb57884f9283b1fc6c924a465b68233

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 61f981abcd197ad0974d193015535ebd3964a88fe5ac6e0042a3d47c45614c3b
MD5 c25b50701a155e9ef6da23ec5b64a329
BLAKE2b-256 cdbd050c50d74d2fb749584c6db1b1d4a76defe64b44caff86b762de697a5030

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f2cf52f4ce2abe8c65c7efee42b6d0c3dce570a16062adf9e8632ef703ad1e59
MD5 10ce1834413517b2bfd85f479838078d
BLAKE2b-256 c69fae7d8cf7b7bf05a03cd25f9f1f026736628578403e35300484fbc250f175

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 149fd58a643619d089c928cb385eaa5de8a53e7e77c35a245b3154da8f997d9e
MD5 61c284152e1deff2b344dfa135677d1c
BLAKE2b-256 a470babd4918dbaf2b66791cc7748eb8ac5fb981b1fb64b707384814a03860c8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp312-cp312-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 fbc9aed7d31da1649e2547cdc87d8ec21ccd06803992594baf3a3bbd072b3a5c
MD5 d02838ceacb5d89c1a0327dfeea24e6e
BLAKE2b-256 e5fe8bbddab431802519319bf4a4d6f6677e0b417b8f47d95fbd87124ba33573

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 73213f6893c149d499d82889ef9b8a4b8fd81f541a1db86d09caeab601041f69
MD5 c651759424004074c10b6c6d6ecc226a
BLAKE2b-256 4acec6b5e5117c6d030ba7ed457d2021ab02bd98307af5a02c389ca090334fed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5ec0841629e2b46dfb13197c07c834c72d540b138a2385fdc9569c1a855a2c7c
MD5 487e8cd9f41665bd55891c487b8ce217
BLAKE2b-256 31170b91f96aefdb2b56268d0048d58c31bb5dd0be560a5ec9ce137e9b8997b9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 e190ae73ceae38226ad1ffac6d40bd75b825465ecfcbf68e40fb96028dfe3fb5
MD5 93661a972407949298e32a797d7dc282
BLAKE2b-256 40c3bbe3d8f2227e93e812fc84b2b9069f21add1cadeddb85e4427cb3178d6a6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 21ddf79a49ffe07f90b874df4e9d72f6edf3e318b57a894884419090f90e4d34
MD5 bef3ad2b08e85c7a87dfdf63e8728d99
BLAKE2b-256 625a33152bf7f17396be3671524a9beb6eae98575b9ca7da463ac16e1d075080

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 6ef473efd8911ca81eddd1dd70c9cb0d246a19f37f70fc8a3d424d04681a03bd
MD5 b928601b8b1ff3a96b646c22c773c182
BLAKE2b-256 5dc224bb8f68d6642225db26f234675c2890a61bf3bc8e9235cccfae7640e064

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 6e2482e2d666726350e29f4076810d92842d67adc5b8555836a3be83f8cc9473
MD5 63a2441649b0e0a55e753083c93fe47f
BLAKE2b-256 8169dad78727d7c30f2f390844f087ca2f87d432f99b35b4c5a9b4cd39df6015

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 45598f7e1bc8ba69bee3adbe8065599795633de3872dc4a7de45f43d7664f8ca
MD5 c23e4a928a9870f6287d9430d738ab8a
BLAKE2b-256 ee304a33d633cde02d96c92af00aac08b1461b92fc483f42011028f276a44f0c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 5093d38724b50ee732dc371ea255133d1c81812bf8d31abb8570c9dd917a7fd4
MD5 001c8fddd108ef45095d165536b80d8f
BLAKE2b-256 616f23f2e97ef28ff931327ab4ba4cc5c2d5911811596849455dbf0913a2c5bc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ba9b88dcef6fbc97657d83e7a5ac8667bf083ed20331b5c634a7eb43ef6228ee
MD5 367810862c05d881c81daff81dfca253
BLAKE2b-256 24b9e3e135ae623d230f01e56a07f6559a05f6a72163f2aacce2a01d47b7f164

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e1bce4f5e631da58d0125631803811bc74ee7f9fa97b770dfa0de09f984c98db
MD5 92858bfb1f694a55d6f6c6fd3f6805fe
BLAKE2b-256 eecc0d91b47e9ed8bd243accc87afb51509984cae2e1bcde95f946d65ae58865

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 c740a02d7e067c241b82c419893666f66b7042b69bd683ae415b1c05bc1ced99
MD5 afe4cd47c923ba5f4f0a5b471dd1972a
BLAKE2b-256 f822247d618f94d13d3cc2fcdd086984665f2d8dc604763e556e5b899cad6fc5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 61716ef12ccad1a73492cd161db9c86db66bef16fd400cccadf33cbe824e6a2b
MD5 bdd7c5a86938a53db53a6e9b71d22e56
BLAKE2b-256 28da3eabb2ef133fb348ca33aa8f339d0e2e862b51966ecdf424a746974f2f17

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2c1a15a4ceff0084cf7eb505a28164299ecbda3b3405891e80e0d6549d7f95f2
MD5 7300d654d6b8c73a16be267c79f825ad
BLAKE2b-256 323e0f87da440744b1848f940a8568901ccda7c0f8d71ab1df3508d3745a6121

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 ca8c8b655e29be52de8b3ab70402931a0fcba69a6e56292c81c4c8748a655264
MD5 b0ce5f15fb4ebc0afd0024a6eaf286c6
BLAKE2b-256 13c7877a31009bacbffe9754b8997d428b38ddc6e3ba8058951875715c6c5e82

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fc58982bd1a9451b839b810a6c87ebb15abdb9f58b130e1680214e7033e712ca
MD5 6e60e0fd2d6e9a0fee7d985c94f04ba4
BLAKE2b-256 6e50f88ce544a5caaad8292e3067eb42b3348e2b8aac34046ff4a8ca8013cb4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 e7b6fb64f0c20fdfc076735b7ce7e49e62f9677eb1fe70dc9b066f7cfb4af978
MD5 d1062666a64056e391a2fd9ad95dab0a
BLAKE2b-256 d3bbda91e53411aec73ee56257005ba4276613f7198eced638392e18ee6c0c8d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp311-cp311-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 384614cf7042154159e6d0c9da24468e928886943b60ac3e86a0c1fe48e1f35e
MD5 cb2129fcfd7196caac8224469a26ef2b
BLAKE2b-256 1243374d6ecd085ec8bc0d23d47f5278681782f5d36718f68311c1290baf47f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 e2ee17d3832c444f99e6fb606932d9e6ad585ececbd5ec6dba8eff0e25a642b2
MD5 424bbbcf3b2cd8ae0dfeb7c15d95e793
BLAKE2b-256 9d014776cab2c0a107adca8e3441695cf2ffd2e4852006565c7617fbf9e5a820

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 5d6ab8d5d6f085b6bd0138ac72dabec32b4b80f0cf7bbc58697ae67592c7482e
MD5 6f1d3334ecf8994e44b8333bbcc11de1
BLAKE2b-256 70ed3522be8bc01e42439f490da4f0f7ebab924689fcef6bbb5251eba62f0a46

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 660d1bced2f654d53ddf7ffe3b221532d15053956ec8b6ee9e35ba6fd0a92837
MD5 55a398b91f1a39975ae4c96b8cc60179
BLAKE2b-256 2116410826ffd0e04637ae58f21405c9bb5165c34fe0c08216e81731a398a262

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8f333296054bc0d19a9dc557695e9eb4a530395987f41c1167963b6e96353886
MD5 34183cec65204fd92dfaf676f3824063
BLAKE2b-256 f3a165cd8b62e7cce8554a9a72e067ad0755d1a8b381d450d675a6f724545a35

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 8bd870a7fb4936cb1ed9447acc85a18f2656a25cfa4085cd5e979be0d83538b0
MD5 f57fda5c2b854b1372da698a62921044
BLAKE2b-256 f203bd3dcab5f577b660083dd3b95e471bc5e282e2a4ed27d41bb046357e1a28

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 67e301bf9ae74c888bba9b9fe03e4108e06386eef3faa22a15abac278a9ad4cd
MD5 cec2986368671ab1bba700b683cc7440
BLAKE2b-256 6d103b0ba98f28ab76fa9f053a1637a21bc93c358da6cf4ed1cd90f0b2473248

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8feccfcde28134b85d82ba5a3e6ce20c702fecf349720e088a6f13376e4b39c7
MD5 4f820e4c49b6a03ce366402348033a43
BLAKE2b-256 32ad9ee232c5631820e494bbc62b662d81710e087fdf6ab6600e3587e169b244

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 f3d5d4c087de77e6405cc57359690e51e8b2cc92252d28fa251cccf5220aabe8
MD5 58760aa9d3c406cd55d72f5110d64ab7
BLAKE2b-256 b2c04e53d3267bdee581473a2541e6803d476e0b59283960e9f5a928c4c9630d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 16906ac9433f39932e0a24c17885d1f27aa1513a977efe9a4e7cff93d3934471
MD5 8aa4ac9cbf71a32befe99d8de5c0a3cb
BLAKE2b-256 c5acd025a4ddc9f1b5888c79ec15141b61081809ec6fac7e6afc4acb376b382e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 33cecb40166c30dfc0698f82ee5f657fda05bd7e1a7d31bb50754ea5650ffacd
MD5 7eebdc8612a809032c867e16e6da5c24
BLAKE2b-256 d3d6cc34db069d3ef23a1c49da8b05967816938a8954b871a58e3a8d5d9e2d97

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 0623450293bd94b87416930997042e2d43e4b9814b389894e188ec142ce99aa2
MD5 0886803686d20503fed57194c83d69cb
BLAKE2b-256 2eb13e5b0d582f697f54a69ce6e131ef494d583b93c1b671d76bd4524875a17f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 cdf87e38800df7e5eefd8bba5e5bfa6bc6d932043ece8b56e92fc80fc96b137d
MD5 922ad097e6ccce20a0cf77460ca2a6e0
BLAKE2b-256 c09a736042c692e1d11837ddd4d0a3af5a9bc1a35cb54b8621f88852aea879cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0ce5ca705cc658910f6437d8e11d1f469566e883bc3032776007d66fa65e856d
MD5 24e4cd6f8e24b5502c03ec0e05611f41
BLAKE2b-256 4555149485a4ba28defc995785815b9a3d0e7ee65fe82dbac1cd82b5ebf8648b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 81873b7544d68544197d53a3be995b35e2fd1335aff6ac44b86e7e839f033169
MD5 eaf4df22dd8d926c8656ab170bd779d3
BLAKE2b-256 32819317a46909e59a2116a2f865129233663feecad8e7f9d730d2aa594a960e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f161bed11b3d63c33d366c520ea64837336f02b943cc8421a6e19fc799b99101
MD5 856e0d2cd7bc7e3967cbdc42c95074f7
BLAKE2b-256 5c32b5f4a7665dd879e4b7a92fa27011bde5ae2dfca5d5c679ef75462a0690b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 1f540f5e34f5befb776b909d766f2b19421feb74e2e0916e782360fd21f71e7f
MD5 8578f8cdedc73b0c267a54621fc0205f
BLAKE2b-256 09a871049dd669b77ac9e21ad1631156e09bc1a815cbd3132bdce54e3b65c88b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp310-cp310-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 def530c20d8e6df4377d022638e0d7d2ce442108203b5b2cd41908a32175ddc3
MD5 062d2ab171b4f3060978a5eaa531c462
BLAKE2b-256 10a93fce6eb09ddf3b4f54cb4d0ecfe0665d577a63f3f0966091a14ff1368278

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 7958f38aac953d7951567a2f72ab9c04e0488c60fe5352b369a9474f4bebe66f
MD5 1897cb69681a30cd9fb2cfaadd5e208a
BLAKE2b-256 85da009a6122705c84818d4ddafdbd80a7e57fecf0671e6a041974955e0d126b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 fec38d42fd5c9509c39c4d5d77191d47a9e5726b1ac3d505bbcf7be4d035cf36
MD5 ada2ea6a9d0473a0dcdd8cb41d3aa5f9
BLAKE2b-256 8a278135e46abed91bb425d38489538d2bbaab26a1d52e660fddab5dcade38c9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.4-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.4-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 29e0c933b80989e7facd01b07f77ab55cb9e0a855b223adcd71ce86ba78b7366
MD5 5fa7f3bb5d75124ed71b373954ed7a4b
BLAKE2b-256 368428c2ce63e9e3485c36e110adb698829539fe946cbc56435353d5a346fdd8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5d2254e00fe9ad0860f1679f398204ffc3502d6aabe08e499bb89b841ba58ee1
MD5 78d7b09ca9a2245e5ff918a78d854f5c
BLAKE2b-256 b877f376263d90347f546cb17fed9c27d069c50d4da0c920a0e1dca9851f3acf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a21bcb0b79ac8f39fba09f6ebce51bf6fc6067925fab5983a7260c8612de9070
MD5 64e2ad08f296fd4c4c8d070b2ea2459e
BLAKE2b-256 1d8ff0c554dcb0adf4aa6d3c0c0e93161b81ebea932bad8900b0fb1c7647ee86

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 bcf8e0aca5cf075dae0cef5483203e2db6c7ca38e5330dfbdb8f09c41f505236
MD5 4929042707e4d817321e2a1369476e18
BLAKE2b-256 67ee300a6a2bbb0716f496463f837ac2b8a41a7657e0da7ca9e9e25b739fc4fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 34cc8ca3938e895f648f431fd508834399f853b86e653085118558a2c4b327b2
MD5 5a010478cdb8476286ec320041c0df07
BLAKE2b-256 f92cc2c605d3306aa85340f7a8b9317d6a37ded06bb7644164a04626def88b29

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 0dc2e7503d2bf87b0ebd7e67d16a08ca7f680c96f09b660258e4304e8540fdcd
MD5 456388b272fc42d69e088192ae2cd8d3
BLAKE2b-256 df090738911468b546ffeb3b53a727882461986bdab98fba69fe6ecc3a956b98

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 fcd6a2f756b54befff315028d4a9de985132e56b3291c8a55b944765159e3486
MD5 09b08657d735bca17723a770047bf406
BLAKE2b-256 16545777d19d7d833c95d524ddce5cc25ba4b028cd2089f9f714b43ab00c7767

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 501c35574fa23a65e5fa716cb11a3e3ee6147442d7719dc32fa9c92bc0c60cb3
MD5 c14e5963cd0bb83c26f7e926ff007809
BLAKE2b-256 63842de22bbc7cd103f6776715f254ee8c6f8686cc26628ae6110a3cd5170245

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a209b540f85144fea8822ea02ae0273b7da56ad3373c15063c72b292ec605f23
MD5 027a9922d786bb8eb686d46a8d854368
BLAKE2b-256 70d3b6ef9ccc146e3669e922b8750c792889d50c5f7446907e978e299b7f8b31

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 d49a7f6794da616c5bffed95fb16c9ba92010af29eca413a87899d05c9748514
MD5 a4de5790ce803811ae72b34accabd587
BLAKE2b-256 0d9d6d1a33b794bca59c29e11057fea5d86c9872ea1dc05a74c44a3d9e666e63

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fadb2cf9434b6799ae1619bbdd0684e37d8d75077aa183d2f94df9418de1db3d
MD5 b25ddc30a19f2ff3223e60b44126f99b
BLAKE2b-256 66ab55dbcd45919afe7c0cb47bf808b077d6e2438873501d7c7c687c640ba2a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 9b444ccfc877fa026e1e8b03bd7581477c744b9d9885e21574f0015371c3d3d6
MD5 075b95a1805d7c2b5c15d611a5181e88
BLAKE2b-256 36660b3da4c62794b9e7085589f86dd0a1939a37759ecac868342b27b38a5a0f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b22ce3101f7a1f4d557ed515730ccfa287c16e608749b6fa2a27d88b43118386
MD5 17dde4754d53d4d3a14f51b3832b88f8
BLAKE2b-256 ebfc91f74cb193d860711de47f59a298b87027caea86d3561c129625a84ab28f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 95ae3d287ce8761f9ac1c0a60df3bfc99cf85a338a016f2a6a87cf22380fac15
MD5 ebff8eb220057c923aa0f009fffe1668
BLAKE2b-256 8317d0295a234820a51329e81267a149b77fe4b27b10d16e1929cce1c903a325

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp39-cp39-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 3eb75a1c5516a2734dd8b5d33b613e8bab26c432c1257be61a75b9a2ca8024f2
MD5 418bd315497df5a9251126af972d233a
BLAKE2b-256 a09109c81d468d16edd1fc0c16e2298312508722fd293053571c2471109adc7f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 dc9598cd09cf64bc60afa17bc3aa594b3b5fc7ed37b851d335c984277ae85a38
MD5 8ae03aa217cd6670a32f1246c1257b3b
BLAKE2b-256 4cd2d9af4fe41f812dc7c1697476b3d0f12978d311bd63b94770cf10ffa7cc93

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.4-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.4-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 504cba9867ec5789ae5543edca2d5ea04180873a10f76b0e368a0dadf8445bb9
MD5 37a0634b1b16d66ceddd44d65ddb821d
BLAKE2b-256 edb1a4b562cb2c7c6782e03be6fc007086509f27b374190ae3171050233f3069

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9e2a72f9b9646aab5bd1bdb31978c29366b781198fc0b0d061bcd65aa9b8db20
MD5 d209da3da5855590178726aa00b0a48d
BLAKE2b-256 6847465b4764c1e7f061d54a2eb6bd0cfd5fbf555a6566e4153e570756132366

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 f4d907138a457c4a9b5e6ea403d12aaa8984268ac97c877e8b2848688d705246
MD5 ec6f7f33701e46179d4fdc161af2bf20
BLAKE2b-256 df6864e5e769ebf6cc597874b2619f300907976c3752c25d71f1d64c4bb80f1e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 8db292258d3cc7ff7d70e8968c27e528707cc8c660473a1fd73fe7873351c27a
MD5 fc13b5276e971eb967e2b8917fb347d6
BLAKE2b-256 da2745b9f4800d383be058f1ab954521f376ff1c0662de459ee9469ba9afa9f3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 0d478f8e02b5a8232917d99f872f32f3d20b8573e599dc828e7729291a999a0e
MD5 b7a4db1218f034407efa0b3a1b04151d
BLAKE2b-256 c4191c2797efc4c648e46e6571da1f5df94c50d08abf2eb4875beb48c3587841

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 f54d385f068d305042c2ede7fde4c02e85d309b8a99264f75df9106d70b62dd8
MD5 8307448996e59e1129ab776c88d9477f
BLAKE2b-256 8b08c794d4dbc7700ebe0f4399d10120833fe74a5e6171d768d322715179c9c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 8e808a7399b0f2a800848d8e1d185646625f66af39441384cddcd5215a9eca95
MD5 744978e9a58443655ff9d0a2e7c58d43
BLAKE2b-256 f39065553ce9096209e2ae0f1c787e45b6e6cf5b891aa93c84e535ab41306107

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c96f46b06b78026bc2a094d44bd26830efa1375ebb38bcb847aa1d7f602ea861
MD5 2acd2c4804995a8a1bccc36a24d17cb0
BLAKE2b-256 5a0b11263169bc2335e88660d901fb5f0cdae3965ca0c4e4c26de5775f759c17

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 13b8658dbfd36a8f99497f0ad0c65d868cbfb777d8ab5c3ab406f3c390f72309
MD5 d3c95ce8f5bc68e51a6f4f03d49fe3a6
BLAKE2b-256 0593b067151cd7c94b334af65796a92a720f24f2af4fb4c0675f77de8bfb4dd2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 35bf1371f40b85ff16bd689ab729f8db0a58feef1d62950fb588f00bbaea9576
MD5 7334ba3e841039504d58d63a5ac18f35
BLAKE2b-256 0652721fff4e361cbf56e4c16dd528352b2015a5b53eed7ae8360fb21652b32a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b3e3c5d280627310872f03a3ed020abf36ba1acdc4780a9b2590c1cc48fbcc66
MD5 d24e5c86737038ac44333f710c09aec7
BLAKE2b-256 32335e5d88218ddd44f2d26684e762f8e746c2f5bf2ab8ddb89ac87b160b1295

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 0b152b29cb69e963154765e7da1683d934f9b41dcf2fa35375debd35812b4d57
MD5 1484df8b4e74bfdd044b4ad714bbd238
BLAKE2b-256 09bd09c7753f0c5021b4f9af4f9bc7836b915e3bdf55fad24906899b031f492f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3c4206de2bb82024dfc66a1d04f71d6d2c9ad839aeefe0b5ecf5440ecc86e80c
MD5 d8a8a417994f7eb33cca5ceebe54ecd3
BLAKE2b-256 f065c2db0b16d0147986c9a7c546dfd874cb060dfab368bd1786a95bcba76828

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 006fa480bd80dab40394e88a640a5a9a922cd903890002064a824ae8b09c9ed3
MD5 928178e536840dd6f160d75e24979ac7
BLAKE2b-256 a5c1669e98ff56d55b7bbcfb79e497a8c977f29859460e3668780d53ec03294a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp38-cp38-macosx_10_11_universal2.whl
Algorithm Hash digest
SHA256 9104ec559f4e190a44fa8cab9de31834c4edb411a4b3c236c8b7d263db6be6e9
MD5 e5e07ec095bcd469649d555b3537640c
BLAKE2b-256 0fb1302efe46d75e5e5d3b6b55c59504f8be540f7db00d9ddd302547934c9b3e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 7d2b69c17437000a0aba0377cc67b9983b594b9fe9695ea56d216b95eedbdf0a
MD5 3e85711da36f619dbeff56ee7d8d89c3
BLAKE2b-256 829f25bac09b94d988840bc905e00b961652ae2c73bd659fe35152f081acc3b9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.4-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.4-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 290956014732963bf47e6ea1ae5efec8403e1b9ded0bfba882362dc7e8fcbb92
MD5 abcaaa63d4891806d22b83d94b1f52cb
BLAKE2b-256 24ea5c6fd8f2277308a6b292b531111250f924c8ffb5fbb4a0b26fea702d62aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b4ec02deed48aad69edb664fa84d37c3f494a55fcc66f64056aecdbdc0b598ef
MD5 dd915f6e6dea9df910125b8f8cd67d9e
BLAKE2b-256 664869d6a855b667b2dc2235234e63e10f3740257e0c9aa8ece6c190c5c6b907

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a418845fae9a2c51fac404541de9b5bc847acb658dcfaa22421a0230f67402a1
MD5 66bc9125eed26250a1f81f0a65c57799
BLAKE2b-256 8bc3393d3980b359b5742454cc9e9cfcbddad299932fa4bf57a4e25dadde7328

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 80a16f949c947304fec78a4cd58aaa90679160e9861f40e2f441c414c9e40a1a
MD5 85cb7c0fd204666f31d0d9f25f3407ff
BLAKE2b-256 56c858288c10543cd984f3982353be7776ef656e919c61db7961996dce3d3fe9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 6433a48f9b4f204968560b13f67d1e194a094f42f580c271d1aaedc1cd60c38f
MD5 38bd223ac559aef5c6912573414fa37b
BLAKE2b-256 50ab5aa50b09a66ddbb7e0a22b45af3dd7600d14777db1c2a42e878cdd06711a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 3bf1e51451754013c525b6c2ffa9d99f196cf6f8cd4fcd46115c60ac893c8445
MD5 ad1d525aace816ec7d8481371c59b030
BLAKE2b-256 c37147e9ef28063a5d93235f19779b90a8d7493cc105a8b9d61c65b3a236313b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 208336a85fceb9c3c29f61cdb030cdf45fc81aa21ee4c5d87444d33afc248c86
MD5 fac35a539f3f6b9c7fd0d877e997dc13
BLAKE2b-256 75706e4a18aa8131f6654222940255d25a52cdf46bd0d3a5c999cf62e8c79904

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b6061cbba89e2231845d4742880ba5b1b221e9587ca1e122ed2ff981055789f9
MD5 260e93ae68a63f9ae897ea4180bbbe49
BLAKE2b-256 a7a63a8397ffa2f365ebad63dad933d5c242acb091517ac22465b17125c6bc64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 b61e519b911a8d9127a1bf4c3bf1a0e5c21ba30fb791baf66db26201a2713e31
MD5 3f684012f0d1d4c98db82e3e1870d06a
BLAKE2b-256 970e0ce7d8e12d1f51e2e716cb93cf0c417f731e756db9a2b3881ea10278ce87

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 fca8cc418a99fcbed97801545c0f9b858c2e09efad11c151616857c12e1e9f8b
MD5 949c01e3351fb69c9eea7e7af409a5af
BLAKE2b-256 bcbc29b2edeed9e855b56b2e13631bb414e5f3f54d2bc8ed0428b1eac4cbbcba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ebda5c2cbc6081e70af26927a9475a841ecf3f6ae7e9f52fdef1e2feabfcacf8
MD5 beb9378c0b1941a39271cb4c962769d7
BLAKE2b-256 e3b03836aed278dfdc9b18d0b8d973c35a430faad6cacef8f50daed377a4466e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1e11b383dbb60140dadc865ac492e6ba1627cbc383a42a5d0fba0df607fef680
MD5 2074a9a41b29d76fab644619c7e39ea1
BLAKE2b-256 932b2cfab2d7f5990c3c6654030cfa735f1d22017a73ea11d02f94b5c4b6a5b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp37-cp37m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 3b66ab031f7ecf209feb4b9ffd86cdb868a5a4cbe452181901678616182bc479
MD5 5c1fd3a5c5d085f3befa1ddad435586b
BLAKE2b-256 eeab5c88a43907226a84bf601178b44cbdabdf5e49f39283cddba8523d40efd3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 2fd60090116c6bf01345aca67f9fa467aa84895a3e3cb0298bed609b4a593481
MD5 a7b56b9e4eda2fad5274a8843feb534e
BLAKE2b-256 52e85480eb529af6a44b70f068e20a75be97943066a27ef9a136ab8e43a3e8db

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.10.4-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.4-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 6e5a5cbab48e15143d58d00f96c6d595dbdcdf3c94b4a51a1d1381b263949545
MD5 dd1e17c0f307d4ced61a45599bf9de83
BLAKE2b-256 cc4d7497ae09ff47cd91d69566049c294f846695aed1aae6ce4dff706de9e9f2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 684649ac6e8e527b76bfb0ff50720ef9512434434c888129e24f3642d8ab268c
MD5 ae72cb6211cdf09ba4a17e2333c25523
BLAKE2b-256 beb75ef50b99e7b2e54e4972a67ebe54796f38ce3a129bb9418457e9f75665f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a16cea74d8d2088a31173f650ec77f98ad3b2f45c8613cfb66e9991ad095cc9e
MD5 ed5a4d49c02db391d2a340f9491822d7
BLAKE2b-256 1a900e34cda5e26fcba1a74cfcc1a42e47a13b60a3253d66034dc6edbe9de295

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 874ba2fbf4a148af94f3e3ae0f269911b2c5c469eca010db561e5b447fd8084f
MD5 24f9ab8808dc55575df6a02c9123b912
BLAKE2b-256 a274c56057e7f71b5fbb44c1b74710982223b461ffdb434b057b309c2d63667c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 648abb80f01b179862115d47a46f8e766a000dd805fde49bd8b72f86fc12a7e3
MD5 ecd268b3e5eb02247d993f86b01db1cd
BLAKE2b-256 9ecbad8041885d03e41bff129b1f908a44084fb0caf7dd04fa36314950a8152c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 c1ceed8617b8bcd910b99d353627e02cc909655dbaf6ba66c279745b58128b40
MD5 09ab4fb745f977f548763fe41bca8802
BLAKE2b-256 5ee8c69672e10792b51bf9f20fc57269dcf78fdecc1d4cc42cf4b5dc034837e8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 41b0b7b25797417036dc6bfff8455ab50f99861ca88f4ec65c6b34b5cfa25bca
MD5 8b0f3762a94130a6ec76fffdc252fed0
BLAKE2b-256 766cfcec2b80be0a6cc253e168d1f40cc2ab5ddf5e27a10fea7f2b7bef4784b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f5de1a78debae2baf795c47afb6e6d19fac7e14c1c142f66d6a3a1d637cb8c31
MD5 545331b3335254a6ee6418d1e78c8725
BLAKE2b-256 3d91d1a98a5cebb8f57626b40ac195c2ca5b683ee547213e207cb55693454a7d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 cca27c17ebef0f92a742e72cd943e7e3aadc511d22f117893da02c3a1d2f0cbf
MD5 269ac2c067ca760c93c0a436be1e821e
BLAKE2b-256 bc3c278fe12af8d31f0c130bfcd2719bbf1c0b791e397f7a321e8b2b95713233

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 bbaaaca25de501f00831d0367132adbbb249caf58ace16c8ef67bf584d69953b
MD5 81c46539e893fc625656f413f06f9923
BLAKE2b-256 715dcd50da221c3531a8838a94bfa719a9e5562bf4becca6b928ea8d00788815

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7133154c32c37538f1b94e506ac5c674a5815a42e7bd0b9141d394460486b6d9
MD5 706b0639ee5a6fd86368e330a9c59e9b
BLAKE2b-256 8dfc5ecf9659a81dfc405ec37cf81088a16e751d314c0225853c644755b82dba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6494e410d44bf6a1593fa0312cf94d1f14a866af0cbfd71c6124eeb12a5f0e1f
MD5 6396a54ddfdda5e3492afc5a65424fed
BLAKE2b-256 28e9607fb22753cd82eac934aef9a18b27b4f1e0ad5709f915733e459659069d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.10.4-cp36-cp36m-macosx_10_11_x86_64.whl
Algorithm Hash digest
SHA256 ea0eff4e0f9805642969cb0679544fa238062fba418ad084f9bd791bf4bf89b9
MD5 11eaf59b2b737d17aeac5b1153179b53
BLAKE2b-256 f3b1be08cd9dc3ccf7d6d4112010d68d18742a7ee49b020ea9a913c4896bdc98

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