Skip to main content

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

Project description

StringZilla 🦖

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 thoughput. 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

StringZilla Cover

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
find the first occurrence of any of 6 whitespaces 2
strcspn 1
x86: 0.74 · arm: 0.29 GB/s
.find_first_of
x86: 0.25 · arm: 0.23 GB/s
re.finditer
x86: 0.06 · arm: 0.02 GB/s
sz_find_charset
x86: 0.43 · arm: 0.23 GB/s
find the last occurrence of any of 6 whitespaces 2
.find_last_of
x86: 0.25 · arm: 0.25 GB/s
sz_rfind_charset
x86: 0.43 · arm: 0.23 GB/s
Random string from a given alphabet, 20 bytes long 5
rand() % n
x86: 18.0 · arm: 9.4 MB/s
uniform_int_distribution
x86: 47.2 · arm: 20.4 MB/s
join(random.choices(...))
x86: 13.3 · arm: 5.9 MB/s
sz_generate
x86: 56.2 · arm: 25.8 MB/s
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 5 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. Despite being faster than the standard libraries, 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 🐍

  1. Install via pip: pip install stringzilla
  2. Import the classes you need: from stringzilla import Str, Strs, File

Basic Usage

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

from stringzilla import Str, File

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

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

Basic Operations

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

Advanced Operations

import sys

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

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

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)

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.

  • text.split_iter(separator=' ', keepseparator=False) -> SplitIterator[Str]
  • text.rsplit_iter(separator=' ', keepseparator=False) -> SplitIterator[Str]
  • text.split_charset_iter(separator='chars', keepseparator=False) -> SplitIterator[Str]
  • text.rsplit_charset_iter(separator='chars', keepseparator=False) -> SplitIterator[Str]

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_archieve = Str("<html>...</html><html>...</html>")
_, end_tag, next_doc = web_archieve.partition("</html>") # or use `find`
next_doc_offset = next_doc.offset_within(web_archieve)
web_archieve.write_to("next_doc.html")

PyArrow

A Str is easy to cast to PyArrow buffers.

from pyarrow as 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(" \w\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?

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").back(-1) == "b"; // accepting negative indices
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(char_set(":;")); // Character-set argument
auto [before, match, after] = haystack.partition(" : "); // String argument
auto [before, match, after] = haystack.rpartition(sz::whitespaces); // 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(char_set(" \w\t")) == npos;
text.contains(sz::whitespaces); // == text.find(char_set(sz::whitespaces)) != 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).rstrip(sz::newlines); // like Python
text.front(sz::whitespaces); // all leading whitespaces
text.back(sz::digits); // 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(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(char_set(""))
  • haystack.[r]split(needle)
  • haystack.[r]split(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; // Too expensive to construct every time
    std::mt19937 generator(seed_source());
    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

Levenshtein Edit Distance and Alignment Scores

sz::edit_distance(first, second[, upper_bound[, allocator]]) -> std::size_t;

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:

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.

SZ_AVOID_STL:

When using the C++ interface one can disable conversions from std::string to sz::string and back. If not needed, the <string> and <string_view> headers will be excluded, reducing compilation time.

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. Some of the 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 is available as a Swift package. It 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.

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.

Next design goals:

  • Generalize to arrays with over 4 billion entries.
  • Algorithmic improvements may yield another 3x performance gain.
  • SIMD-acceleration for the Radix slice.

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.

License 📜

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

Download files

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

Source Distributions

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

Built Distributions

stringzilla-3.5.0-cp312-cp312-win_arm64.whl (61.3 kB view details)

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.5.0-cp312-cp312-win_amd64.whl (67.2 kB view details)

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.5.0-cp312-cp312-win32.whl (62.1 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl (246.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.5.0-cp312-cp312-musllinux_1_2_s390x.whl (175.0 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl (209.3 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp312-cp312-musllinux_1_2_i686.whl (190.7 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl (185.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (252.0 kB view details)

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

stringzilla-3.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.6 kB view details)

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

stringzilla-3.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.2 kB view details)

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

stringzilla-3.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.4 kB view details)

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

stringzilla-3.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (191.9 kB view details)

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

stringzilla-3.5.0-cp312-cp312-macosx_11_0_arm64.whl (69.8 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.5.0-cp312-cp312-macosx_10_9_x86_64.whl (72.6 kB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.5.0-cp312-cp312-macosx_10_9_universal2.whl (110.5 kB view details)

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

stringzilla-3.5.0-cp311-cp311-win_arm64.whl (61.4 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.5.0-cp311-cp311-win_amd64.whl (67.1 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.5.0-cp311-cp311-win32.whl (62.0 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl (245.9 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.5.0-cp311-cp311-musllinux_1_2_s390x.whl (174.3 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl (209.3 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp311-cp311-musllinux_1_2_i686.whl (190.1 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl (185.2 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (250.7 kB view details)

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

stringzilla-3.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.2 kB view details)

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

stringzilla-3.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.0 kB view details)

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

stringzilla-3.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.4 kB view details)

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

stringzilla-3.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (191.3 kB view details)

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

stringzilla-3.5.0-cp311-cp311-macosx_11_0_arm64.whl (69.7 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl (72.5 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

stringzilla-3.5.0-cp311-cp311-macosx_10_9_universal2.whl (110.3 kB view details)

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

stringzilla-3.5.0-cp310-cp310-win_arm64.whl (60.3 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.5.0-cp310-cp310-win_amd64.whl (65.3 kB view details)

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.5.0-cp310-cp310-win32.whl (62.0 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.5.0-cp310-cp310-musllinux_1_2_x86_64.whl (244.3 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.5.0-cp310-cp310-musllinux_1_2_s390x.whl (172.4 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl (207.5 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp310-cp310-musllinux_1_2_i686.whl (188.7 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp310-cp310-musllinux_1_2_aarch64.whl (183.6 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (249.0 kB view details)

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

stringzilla-3.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.6 kB view details)

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

stringzilla-3.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.2 kB view details)

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

stringzilla-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (186.8 kB view details)

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

stringzilla-3.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (189.8 kB view details)

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

stringzilla-3.5.0-cp310-cp310-macosx_11_0_arm64.whl (69.7 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl (72.5 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

stringzilla-3.5.0-cp310-cp310-macosx_10_9_universal2.whl (110.3 kB view details)

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

stringzilla-3.5.0-cp39-cp39-win_arm64.whl (61.4 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.5.0-cp39-cp39-win_amd64.whl (67.2 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.5.0-cp39-cp39-win32.whl (62.0 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.5.0-cp39-cp39-musllinux_1_2_x86_64.whl (243.3 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.5.0-cp39-cp39-musllinux_1_2_s390x.whl (171.5 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl (206.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp39-cp39-musllinux_1_2_i686.whl (187.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp39-cp39-musllinux_1_2_aarch64.whl (182.4 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (247.8 kB view details)

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

stringzilla-3.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (182.5 kB view details)

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

stringzilla-3.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (209.6 kB view details)

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

stringzilla-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (185.7 kB view details)

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

stringzilla-3.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.5 kB view details)

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

stringzilla-3.5.0-cp39-cp39-macosx_11_0_arm64.whl (69.7 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl (72.5 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

stringzilla-3.5.0-cp39-cp39-macosx_10_9_universal2.whl (110.2 kB view details)

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

stringzilla-3.5.0-cp38-cp38-win_amd64.whl (65.4 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.5.0-cp38-cp38-win32.whl (62.0 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.5.0-cp38-cp38-musllinux_1_2_x86_64.whl (242.6 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.5.0-cp38-cp38-musllinux_1_2_s390x.whl (170.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl (205.1 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp38-cp38-musllinux_1_2_i686.whl (187.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp38-cp38-musllinux_1_2_aarch64.whl (181.5 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (247.1 kB view details)

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

stringzilla-3.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (181.7 kB view details)

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

stringzilla-3.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (208.8 kB view details)

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

stringzilla-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (184.7 kB view details)

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

stringzilla-3.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (187.6 kB view details)

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

stringzilla-3.5.0-cp38-cp38-macosx_11_0_arm64.whl (69.7 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl (72.5 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

stringzilla-3.5.0-cp38-cp38-macosx_10_9_universal2.whl (110.2 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-win_amd64.whl (65.4 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.5.0-cp37-cp37m-win32.whl (62.0 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_x86_64.whl (239.9 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_s390x.whl (167.8 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_ppc64le.whl (202.1 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_i686.whl (184.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_aarch64.whl (178.2 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (244.2 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (178.8 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (206.0 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (181.5 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (184.6 kB view details)

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

stringzilla-3.5.0-cp37-cp37m-macosx_10_9_x86_64.whl (72.4 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

stringzilla-3.5.0-cp36-cp36m-win_amd64.whl (65.4 kB view details)

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.5.0-cp36-cp36m-win32.whl (62.0 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_x86_64.whl (240.2 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_s390x.whl (168.0 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_ppc64le.whl (202.7 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_i686.whl (184.7 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_aarch64.whl (178.5 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (244.2 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (178.9 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (206.5 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (181.7 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (184.9 kB view details)

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

stringzilla-3.5.0-cp36-cp36m-macosx_10_9_x86_64.whl (72.2 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 bb513ae0bfe6f98d4a65a8e182a3e9184360b92f907f16629cd928e412d0dbbe
MD5 4aa9253e796d1bf2bb9df87310787994
BLAKE2b-256 6e9f40c206caa2d8a75c8da7b42ff38e821280088e0b759f1b24251f43292a64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7a0b2bf350b9b54882ddaef27be638dfa2052a0c5629495a2b27e6eb78c9924c
MD5 39b44b8d22d21ac601486aba547f1240
BLAKE2b-256 2287cf562a1f216b24afbec986b67ddb9921fee5665187b4a28587069f8feb9b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp312-cp312-win32.whl
  • Upload date:
  • Size: 62.1 kB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 9f0c2b90e31dad82abcb6f9956d6395efc71c5daea3297eb97e6f572cb437401
MD5 1e10ea7f3b8a9232772a00523db18ec6
BLAKE2b-256 4fdb8d2a41fc71e88597798a7aaf4a93a3703324b1d892688d1a75655305cd26

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 70e25ccec06e840eb320f02ed32ea3bc7941334adec2bb093ac7fe5132224aaf
MD5 f77bcf6955078522121f4e4c51ac17f2
BLAKE2b-256 7045b8828d086b01e59651e3a227f387f1c7d116d8ddc0afd55c7bd774276d02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 fbd696c472e5b6ac7bbaddc403ebeb2fdc7e5ece86ea15e3b218d15427b383e0
MD5 2f1a40b98f6dea665dbf664e34f7d78f
BLAKE2b-256 feb5826382c9d1cc0e76cc09a758ddfee3debb321eed88b681b157130259cb12

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 4f9c95e1355b499a576a3c65263afaeb9027e4ac78b4bd40c4312fb9951d0c6c
MD5 6e4e770872a68671aa169e4ad02c1146
BLAKE2b-256 c89ff25456ac3a5ba8e81f95e3434885583f8d7678bec0cb85efe3c52ff6031b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 83ab1232453b4eff38fa3c5988c517ee21fd2898da3e506bc054ef11abdafba0
MD5 2ab59fe990b40e95ae32d64f5acfbbea
BLAKE2b-256 29c37ee44473d4da7588359c62059cd73864012f92e1e52072f1059fe4fd95b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c33c381b7c0717ce0511f31148a26f355002d34bd408c0fdda5c486aa525c74b
MD5 8165ca2d529e33a9b39c80cf61cb287e
BLAKE2b-256 8e844e8c713ccbe607974300eef3a36d4a80dee5c80f67dd1abbf91d0b930610

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 52697be9bdb40604605772f2534562f44cf4892aefa9c39a1dc02b059a5aa579
MD5 a0e0c033f9911c7774592948cfd0ccb1
BLAKE2b-256 1179fa83e84231b674cac4c33807ef0a26d70f22fb6a8c56c7f943239aef08dc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 d370617ea2969f7934a8ec635760bdd5dea6fd182fd86b68d645b33dbfd6116d
MD5 e81208f4c9506c4d2d3f2bfbb83243d9
BLAKE2b-256 56b0395dbec6c9637376ab8ad556d3d514067257b18ee5d6e7521581ba5004f5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1483fc92bbf860e7348343b8480c8662cd666bafcc19b4fb2c6b76c466c2efa2
MD5 d2ac88fcc5fc831bcebd89eed07f9db4
BLAKE2b-256 7065b749cf5cb98d95bb63dd09594d3f230aa269b3b8ce0cd047c21be34e3b38

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c744558f1dd2e6f618a8004224b4dc543a0f5b9662636192fe7969332768fa92
MD5 50673db21ac20f6069e3ff2ced80b23b
BLAKE2b-256 fd3257ef1b209f844d61c3136ec9948fee4f47a77f8bcb92ea4732239508d67f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1818627f622aaed5df6f927f0081bc15750ae4b0a799b831987648dd392ee073
MD5 f622510141fa44d296630d450fa91dbe
BLAKE2b-256 f269e1cf2fcab269420f4a45b5babb07fe6390a95385ef10273b18956dca23b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9c8cb00d6b3d61d41dcc2a6982ef3c6b1fd45ba3eaab88f2673f10d2685d5199
MD5 df576c2c5129ec5b76ea76879d170e77
BLAKE2b-256 34182441bea6c6d136f2229ddf3b1bcafb30c9815ef67cdd75ee4a3fa7878388

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp312-cp312-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2e813bb0fd7d3fbb90e0d3c65bb25ded27268b4822e280a2184b958df51536ec
MD5 c87c53cc4fd72eae191528e9503aea32
BLAKE2b-256 05c3aff0ccabb4f0ad2514ccc37a758a29d7be52c3308bf255e40b4d46449d9e

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp312-cp312-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 dcf691856f257bc58a48b5f0b29432e0316ccf2ef5fb1982719d457ea455d173
MD5 7c98cc3e5b5d5a47257ffefc80464ffc
BLAKE2b-256 11895e1e17a38e83dda6f29d031992e1128e03fd5c71deb44d10b28edbb12600

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 d781c34ddb69a105ee6572a35d628809d57d885fa6d9be147fadfa18487c4e3d
MD5 ae9233b79b5f8a6dbeda01f9d772240a
BLAKE2b-256 10545257a8744062cd9545e2e6d62a500b7caf09c1e1a62acf7a0930719e322d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 042aca6ccd70895b40d46385ec18618ecd36b02e8ea70f134b135508f23be098
MD5 4e52588de37f67dd977e430610009d0c
BLAKE2b-256 24b62a1236e4f91ae42cc8caac34527154ead679b92f48ed34c86cf601c0bb50

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp311-cp311-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 db4e62e7e8101f95c14cfbe611204f7c2d7b8676d95fe281d234e647338050f3
MD5 0d4a1ae3dfd1932b3b696870b41caf8a
BLAKE2b-256 1a28726240cefbafee2fca7727870cf9f31127df2ac3a5190c3d9ca1d84d6641

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 c9a50581a1a98dab4ff834138746f57ebc960de893cd51ceed5de5e7ec6fe4e4
MD5 50e625c28ae78574c99985bf561d0281
BLAKE2b-256 d245a8a2b47b50da0d03897fcc4d3d729473df4ef8cfc9cb31b5284772bc6279

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 abb1a25fe3d15f5e7b97b40370dcc519d36d75f5014727dd174984c8ce47f9e7
MD5 aa12964a3dc9b214848992d87ac553e8
BLAKE2b-256 8612d7879011f46f60b46f10c6f6e80711a738372c97a4b7e2117c44c053a026

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 4ebf699a2a00418b198a1fef540c6bc21a6b5783c03300c4b0dd6567427089d6
MD5 ccf0c50fc7a39bd7642889883975105a
BLAKE2b-256 8f53c1f00695d6b0d8c15d5c4badc6c79468aee99d9afb22a7a4c759642143ef

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c6d9906fc7b89f8d54bf1908643b736363d710205b8c05bb975849c6c19c6fde
MD5 3558682e3e8db3da530985fdb6d5b3a2
BLAKE2b-256 1e772c4083947f97c7fdefd42e9570173ca32b7833c5d5598a26a1e81f87f980

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2952996079511c8946b8cee04798df23f435c7c588cd26e0935ece13b5826fba
MD5 59c4af003c86c1833ca634796485fbbc
BLAKE2b-256 189fad3a3ba786414cfd5c820e5fbc241436ddbcedfe18ab39cb83b3fce62419

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cd457bc77076e978855bd6051f11420d4ee5d213159d0603ae1270a3c8bd3151
MD5 049a9c5e71010be55da0eab6a3deea5a
BLAKE2b-256 920b7ca274c8e5e98735974301ab0e75cf85a9cc0dc2c24670879c8f540b39ba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 15b482a463594821b091b30d0d41090bf3f0413fab18e91ff97631f0cde4562a
MD5 6597ef3e0e72c6480c73223d9a0df578
BLAKE2b-256 ee550ffcecb761d371e8e3da88fe081b0a4c781a7dae94633afdd6cf4b059db6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 d495fd3279c702fd9062ca975af4f548d46055ee691d1d75900d74fd8270494b
MD5 425cb49fb05dbbf53f6053f37bbc6447
BLAKE2b-256 f9eb8e9f82e83e483589b27673342dff61cb8dd6f577a9d0baf8ef9f61089705

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 855050b1ccf79daeee401b652eb1e351cd6bdb909a7ace1490ff2be7b063318f
MD5 d7fcb13601e6f1e736018c3c8159b5fc
BLAKE2b-256 67ad6d40b0d0e35c43ccff3c25c1d686d475f5bbf1685cb815ca3e0ea786513c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 80f0687d5f4875113c709a0fd77762e827a9030888838bbc85a0f7f3c4bef55d
MD5 b1c92f47e95676927c9f67bd7d983520
BLAKE2b-256 281636694b9fc690543d99a0b3a225c4b847e580360203f8907b9c20e3d55308

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 216d196c3416692c4ea8350f7adb226460d3976990ab8368215998443c2aeee9
MD5 650e2343aa16a712cfade1f0bce4b81e
BLAKE2b-256 9eab1948f4da8f38bd86a292cef429900add0ef7415fa992df7cf227a3d291f1

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 739849b0e83056904bef310d03fdb2ac73b019fc6a072e35415ff7ce6875b46f
MD5 3e71c94129e7fa9c4f90e630f18de3d8
BLAKE2b-256 ebb03c480de219494235abb751c872353e898f46513e963c02b5b46511ed61ee

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp311-cp311-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 95ad0867830aeb3adc5f5f510d1ac72c2ecaed83551680ed4b2ea71b0fe5ad07
MD5 d98bd8cfe77b8cc97a6eb053b691f9be
BLAKE2b-256 f871ba900186524f073f84c186ceca60d5273f5fd8950e10083bf3cf69017fdc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 8767713bd24579f78c5deb7aeb3543f7b795556c5fb70c5ca0d22f65ff44532e
MD5 5a344b858b70e4c6c95b1ec8da0bd203
BLAKE2b-256 75da7ddfdb80be7051a4097568c7897f11c5ab0a085ca9e60e9a080504bd9be3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 cf84c9dbc7d23f33436e9206afcba1a91c31bc35d78b1a6e81feb34f968135bf
MD5 5e1d117f9535e9ab4d1b90be99d590c5
BLAKE2b-256 3a8cc1ab6e97e4eb71257423c3bcc14d4458294794bd416cb006c76fed44f214

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp310-cp310-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 26f1ec12d063439a2e9ba0e9039fa694b734e1579d9756cc8de52fa3a107e045
MD5 117aef688de898eaca66ddb8cd248cad
BLAKE2b-256 91579b62df5c5a0162bd78e6e76c69b57a613fc4ff29d1c41d087ba201b304fc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 2ac29c19a873b3b5e10cffcf7dc0d2d96a71b803d34af0413234e64aeaf12306
MD5 f36fb0fdc718d9b86cbd96d4137f730b
BLAKE2b-256 bedefef5f852ccc534c5fd08ce44c7edf9913cd5a02634d1a4283c7d09ab209f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 34eefa50e702366c2cb2bbe751630f5b4c268fef5cfeabe6e2a2687197094083
MD5 faade5aae4f80405b27895fe07409726
BLAKE2b-256 b51756a49dd6a251ef3cef1c178d9e6d6631d23b5735595244ada6691567582d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 0a0999277cb7b0060061d555862b575deaadc32da0b30f48e2c6c40bce723e91
MD5 97b96cc5d5726cb0e9de0e2118d8e520
BLAKE2b-256 cd7820be8832d640d848d63c06c3f0aa47edc684e2bfe0376a9281c129f0428b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 5ab02b12dc55ad4d3afa65579cc9477fb621489642406811ee55ae5b29bae656
MD5 56f07bc5861eb112a0fb889dbfff6faf
BLAKE2b-256 926266a16e5419f11de64a044ff1fbc6e47ce0ccae5d29de94a503022e74a4f9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 34b6c792133f3459bcf967ebecbdb74de9812865edf728c9bd805b2fedf00634
MD5 faaf0fc972ed6b96ba685e056dd4ad92
BLAKE2b-256 5a4a15adf5fe55ce28cb9c851eb8a659e0709523821b5fa103d306817d93a0bd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7c1c523f9a09cea21a2e4203155489079371cd87f4a80cb772c7fa95c9d16160
MD5 b1ba55c58cb4587813ee88050f5f0330
BLAKE2b-256 007c0e278d2b41b1a4541f67d73ddf7c9e606396dc7f3a77033a1995e75c7bdb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 af41c161e5bb7be6100a78428c6b95f488b36d5343ba646dabfb1086bea13796
MD5 9f146f6b9c884b9c8cf4bf1011420c1f
BLAKE2b-256 89dfad74d658f5eab57a48721be413c33c742e1b28fb2c9132275706deddd32b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 443a3d4b0be4b134278dff3605d77452e88a298334e985ed62cc127cdb5cbf10
MD5 23f136669f1519ee91469ce1f623705b
BLAKE2b-256 3a1ef0338d9642c1433bb3f2d01ab8c5be58896e413330b6706cdda0d2935796

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 82d04639c2943e5b1443d439c01290ef96730922145c1a104a0dd163d2a98e3b
MD5 49d1ae3fde456cd7a367358b91cf17c6
BLAKE2b-256 5c7356ca75ad8337c98a0cd0dd7c8d0e8e285c1e7674a92497fcf143e4e74e20

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 77ce9d41d032d1fa0a15ae0672a5d22361c61627ef88ce954f8cff7ea55dcec0
MD5 c91fd4b4c8de945b24916bb3af4559ed
BLAKE2b-256 9684e77298f0df02774f174b223a54b5f76f0bde7ac1a907b666e7cb904dc691

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 eb4b153aca647ad54a7549c51b4b91832680d5e113e5614f68cc9a10f2f0c099
MD5 28dbb50db4c3190ac510981ba0a8581b
BLAKE2b-256 542d37c455bbf89368816f902d54089c3078058213f175ee75dd6bb8a22b37f8

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 2143058842a997fff17c9ee1fa2745cee78d8573f3640a9b9c07de1b85cdfb9f
MD5 c374aba12c929e74ca46fb3e612e9d1f
BLAKE2b-256 bb5c459a8f8b15af0a3b2df2d416e82c95ba850e6463f3e7a0064c5600729045

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp310-cp310-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 9245406bd532be4b60cc9cdcf97fa3ebbcc958498e092b6143c8b9aa331b3346
MD5 97696d8ba91578fae717724ecd4e063b
BLAKE2b-256 e6bb2e2b4c514a8cd94a6fad8aab91d47980da288d77b629f8208a3a4910bf03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 8e08a89d74e30306a9c8d501029873cbec2ee65c013f4edd13530683d4829188
MD5 c983a0612d4501fdf8e9c8c0c2e90fe2
BLAKE2b-256 a2cd0578efb66bfa7bda6efd4aeabb600d2e08e348982264051f6a67f81804ed

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 6702c78fc18d60ac8f0d77aa47c188eb56c5d8fbcb62e22e772ff5269d55c2a8
MD5 1899d95dd023515d5b98d0187416290d
BLAKE2b-256 c78d059d298b4e53db0e6b425fcd1bc30d75f3af49284fe84167747016cafcdf

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp39-cp39-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 43a512a082a17f9b4093777d58b34840016c08ec44399f8d70fb82dcfd8879c9
MD5 e0bf85e2d294bdd58895aba7fee354d9
BLAKE2b-256 661591316d0ea8dc58151a10f675351b303dd0a5ad570e26c4c136a6e7f3a5c2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9a528ce6bf9a434744dde7abad50109b79e6556ca8f8244245eb47b9becf0270
MD5 0387c2c40fc1ea3cef9352acccd96bc1
BLAKE2b-256 95c6bcf848ebd79ad8076835f808a597cabfd7893b41596a80ad222f53cb7c23

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 4c13b7ec6c5cd018dc4bbc779fbdc1b61e0b04efccc5d3f8d2570877fbcf8ed9
MD5 68752d5c549003f23c1f61eec737470f
BLAKE2b-256 ddbc384183d4400c5229842cf55024ede4042121884f4816d9ca4108551d17b0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 9299d4cb62791e56cdc4a66cb711bc8e81917123e25d09656a1f600a859e6043
MD5 f98893e0c636ba827294194abfb85231
BLAKE2b-256 be76f00d84fe8faeee053b93205936e436b156ac0b5490df68c619e0fe581537

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 f6ade8e3a8ff9734edef7bbd5034b683d9900199c37bed899dd13d8864ffe1d7
MD5 231ea86b973846cf85dbcb57c7274a76
BLAKE2b-256 859f0caa6c67aae125d03c110255af691d217adeda31431e372dc8447398d1bc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4e276c6ece979539cc0d81f001e4c9ec9b27099a3d6f5bba2f78cccfd3ca788a
MD5 879a7c827c36dc9e2327152f4cb37e12
BLAKE2b-256 e27c618faf36306274c39c602cb3322e27ed16165e8d0eff66595af84ea84023

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e138feb8eb24d74a6c291b8b037715aca238c961699f6143b3f6ab6ae70afdee
MD5 414dd1acf96ac4532c5b79ec4b558a26
BLAKE2b-256 b90984f40a2b367483f39c829d8c5021b7466dab58a6d3852151cb712de84d8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 438924a84f1eeed53fe676d8da26df725b93a18febed67fd93ae60f6c26e46e2
MD5 1d2c4e3ae8593c3c53e97fef44d1dc3b
BLAKE2b-256 13b5395a1e703896122d1066eab20e5fb0df9f2fe74dcae4484cbe0942d0be44

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 b7e0f16b842ff2702b428dbb6839a77379712b76ab8340568b3955fa0a4e38ca
MD5 ac598063bebd217825a7ac351d6264d6
BLAKE2b-256 dc37fc9d07fbd1e2eeba474fd84b5c6c698a1c99b5a58c304f3d3aec5d2127e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 05d372514c41b8003893a4b5e3564cdc640c1c3c1987ab2ccd9d71b111abdcd3
MD5 1eeefd00b9e6a935cf9e981c2f2e1649
BLAKE2b-256 9f6bc5fb5e613f8a6b96ef5ab429a1394d8100179ed1249ac4ded0e58d9e7026

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 252430f608f08d05b065be76c4c682e7f2c95fae3f799ab63b142919026654bf
MD5 58e38cc4a7cf9ad18c990c3d7413ea23
BLAKE2b-256 84b856aad37834ac0a93a6c0d984d298bf619c254f2594fe0701cf259eaa870f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2aa3644c0d50732e3b8535699b2c27b1daed19d2eef338ca4c3f159fe2a0fe69
MD5 1d949477a7d5b8dda3075166b54019d5
BLAKE2b-256 b54df2e4283bbe898d7a541a6b5e83ff4dfaf01271b86e7456d2293d7e74c10f

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 8111534193cfaed3853fd854bb471be11bf5fb403d22bf921f33f9fbf6704a26
MD5 b15fba530726be15bfefb7d14ee75593
BLAKE2b-256 65b6d9f0d4a5a4a44e34cb4980d51e91bb056a073576f17d64ab40e56a88949a

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp39-cp39-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 cfa980fa9a44598d385cb3c107192500b0dc951f6caf1fb213671d44ba69f0a1
MD5 7c7e4fd6573662016030e2893f3acfe1
BLAKE2b-256 c3f9dc65d761364a17981a17a72623fb0735fc732d771019daed08fccf4fa95e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 9ef09d1150a31b2a0e86c5d9df156259e649ab8bea4b60049ce5bbd80904d935
MD5 c25c8312cbe886ee67d1d497a908fb3d
BLAKE2b-256 aa3f495a9c43967b84f397052dd1c7b9defd5ef046d4145178fd329116a86bde

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp38-cp38-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 3251f0370c32f81ac72d4bc2d58f124a9eaf7fe3175d7f7d3f4dd1698c74956b
MD5 250735a131e80129f146ea8c9e18796b
BLAKE2b-256 542be76d6ea53d8449e353ff57f58788b93f03904c326771b4f97dd3f49ac205

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f7d274ab7d0032ce0afd0b6606973c631a94a4999c44b853a1be309464f179ee
MD5 5713481c4b5b8dcf4caf9ca30b1f852c
BLAKE2b-256 4a58defe0b9cca14fc9eb0a45ad6dd49b7d4a517f1298706aae0c7ecc4ba7e95

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 e698290cc399dca6c4ef80a5c904e122818a7bc3f2c5ac2672351f593c94182c
MD5 0cc1d53240870492697600feac9dbd61
BLAKE2b-256 b9e9841a5abbf3d9c7eae31da23feb08243812070b0f64ee0934854d042aac36

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 6fada390eb7441ad9b5f246a2182cad7318c0015fefcb5923827b98dc1dc67be
MD5 348a465ccc6ed1050fd6a8a8e8d55849
BLAKE2b-256 450694fca473b5d0dcba0a8b95f94fbf37597d4051afdffd3df12e90b54d3899

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 2423f8efaebfd68a25fbf36dca220095bc9ffaa081d48945946fcd97f7e10f20
MD5 d290c20f6e8338d155a6e3dbd35f2bb8
BLAKE2b-256 a9398804cfe842dc09cdb151f3e52e6f4fb3adfb445378fb9baec24c13af4953

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d814a2fd77cb76f4279a22d97f950841a6afa8a2185a69795e3c9ac5a6fad150
MD5 eec04b1493dc5dd2107795d68e747b07
BLAKE2b-256 7e2917cc7086a07b68fdfbd3ee3f8df550256c4b5cebdc65a7436fd7c1a9570e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9b92a0764be3a5302237b884eaaa4dbb2f0c1199aea808f700e6249da61834ff
MD5 140c077426fa62ee68ce3ecb11a1d64b
BLAKE2b-256 b98f2b10b7312c1d1766ac935ff75fcadeafc4553e0ea9f8780e9bad982c9c5f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 37068b108261906578ef87004876a3c5428c5bb142de74e2acbf60f1fd2c6894
MD5 d22e23d2cebd9ed836ba47263de74f3c
BLAKE2b-256 b57c5d15c27c7f0a2c3685abb5497317bb4608b31afbe6bb7a86d94015a131f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 4dc058654b45541885686634d269a4bd4ece2363be57431a9e44750faf53f5d0
MD5 e9e30116effe152c55b086d26a4fe92e
BLAKE2b-256 c1de417cd3b326c196dec02120afef7f0dd1c93eb9328720956b58de9525846a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e4b5901e557fec100e57a9488eb60be048abc5c8cdcf26c98800ce591734373b
MD5 12ed5ff2642482e3b220c7717a1d5b6b
BLAKE2b-256 e3ffdb66d41c182f096ce5780f294678f7771cb783d07901f08455b2712f2124

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 652889cffcd2166c6f108da7e30a16f18b8677d7791a67f25b40868917980a15
MD5 cff94f63a7ad1f483fb94646b37695ce
BLAKE2b-256 7061a47547671fa2455ab22b09c227ca23d560f54ad00374bb25080ae9f45ec2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 35d926872b6f8f524a3d7c90c506ab07b0acd80d18cdc8a3ac4546c34af396e7
MD5 0ff86cec3b97f858de083b1820673816
BLAKE2b-256 1582d2c7bb2e85580fdec3deed7908cdade086876865c156e543340e588bc673

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5dd950c2baa08b8c21776f33a64b994127023c7d3c473b356367070e16f200b7
MD5 186aaae07cecfec6fae29fe7d1a61102
BLAKE2b-256 edbe5b1912c8dced4cfcfd6f3ad05c87c8fee3a4f9440d7e1bd4abe61b7c347b

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp38-cp38-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 cef4ee3c2c8882839541d0528afcdc8dd9ec0c906c2700855937aa126a764671
MD5 b3fcc2b5917fd036da7d0a99ced8be5f
BLAKE2b-256 5795c0dc6d7945fe79b11bfbc2835a826787625f9b38a7e45d114c0dea288f96

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 c6fda775c3fedabfa9e3bdb593cffae75c7fa0214248053b9e40d16dd6693d0f
MD5 12ca0063f585c8cdf10ea29c98a883fc
BLAKE2b-256 1e1fd3fd6a7deb58c4234538c8d2880229287195adf199df4bacbde392b1b1d9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 54cc7a659a06f42a0f834440dec1ee99b6c0b35c54f3f6f2cf973b54cd9c8e86
MD5 fe8181604119a62cdabad8a222c056ef
BLAKE2b-256 25cad5102edd30c3cc77dde093b3faba24c4b9f5d9ed5552e335d833cf63096c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d41d1cdead3114c117b40a48ca6c005bfa8bd6e074dfe4e94e78d9088a924895
MD5 633e739911dac6dfc99f7a8a94fcd344
BLAKE2b-256 9acc328c36a1aa34208140671cb9a9684964ed74506fed2a9592a93abf27f3b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 9650b8e8d0113e9370fc16fa65e2ca0a6c6cb88666019f27f13295d103d55234
MD5 4b02386f05ed523762c5ffab2ecd3394
BLAKE2b-256 5b52cdd92c5f2a41775329e6ad6a87c71e6cd5dc6b96ef067778cf0fbf2bf53e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 54631f5f2a2d422c16a18d54a8136b08957418da450846875e72401cc5d7ec81
MD5 f95ba58e568cb0f4f7e268e945d8dda8
BLAKE2b-256 1c9f72cc05eaac5b260a8e092448bbeabec25b3343b1d55b452be672944268e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 376ba2c854ff2e20f5ef72e2717c46d93831c9ac42e9720da70dbf88dc0c0292
MD5 fff77aeb0a21541ac45f50ad13f59165
BLAKE2b-256 8b95a47d295837481bab82fc09acf17ac187e1226e49e33bd57e5733a69f320c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 8b513fd579938ba2777e693d6cce35edbeced96a78428438e8855fdda7ba91ba
MD5 82ffdbb1afb3b98db7be6695904d4bdb
BLAKE2b-256 40fd9db5f5bfc031bb6e252b2e9f86d753d76a0f38f2b6a15c4d3ea74a0013cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4c7dc9e1353ff0666acc4f5431d0faf0d07f147e8ab0af87592a7d6bbdab25ad
MD5 fc0077bd90b685c7a4fd19602a3ae789
BLAKE2b-256 48db3e133ecdaf93e3cd23ef009e2de7cda2bb1bdf31d9eb5d38eae49fb865bd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 d363adf85fbd97d0c09f48a813d1af680ab314320243ffc21c74534cf9401bd2
MD5 031fdfb8dc7abf9838c3339f314e70af
BLAKE2b-256 7fa6bb79555bb75dd3e63e62ab4ed66e4728d315a35fdad726a2add9761e00fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 528c4858627af65422f9c2b69f5aea4053176de355c49311b514e0e3947fb9a6
MD5 65afeb3456ae194b4d417e119881d37a
BLAKE2b-256 21f0b497fe5822d63d28ebf4259fb8e0d63f519afc4a2ab5b5ee2d21b4e06fd7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8ad4518a0202340aa10330ac6db0340338f81832f06c5193dc3928aebf8474b5
MD5 1870889ff939387fb6fca94b68f7c9f0
BLAKE2b-256 2920b32a3cf98b048fb628258c1167d7a4a2a2010a77577d784855aa87ad7491

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 00c591606542e73eb41b4e8ad1ab74c4070b7eda0a12831036c7a7874e23803a
MD5 25f7041b717ef4c1a0168fbee395df6e
BLAKE2b-256 3d7ebab7291f3cffa6e399eb7996d5439300af554049bd9d9316d1c977e72b1b

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 5a42b6c108fe64541043d1a04d933e7b49be1fd3838d7a210cf960f1cc503908
MD5 705c0a713d392a4efa362fa98c09e23f
BLAKE2b-256 819d4dd38b2b2c3cfb088218f72f3da5392dca5461ac6a82f23dd263a99ae9ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 6961b722c234c174276460a5c731b9fad8ac9a54fa82fed00dd4964379145b03
MD5 5de8b7259acbde92e3d5beb1070a7890
BLAKE2b-256 5033132b774f774ec567bc30252ddefefc37c79b8d75bea3d1b16afb42bcefe1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.5.0-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 62.0 kB
  • Tags: CPython 3.6m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 5c4d3e49a63eb41ec8b95cfc080c084a23a9938d8276d3e468de0524ef30435f
MD5 40f596347414789e60f3552384e7f5b2
BLAKE2b-256 e675e21a1c43870c037d0dd1248401116364ff0a0dc448293fd7ab4b942d2d37

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 efcc5055913c8c62ace801118252a1d9635dd9cbf40ca6220e307a90880a10a4
MD5 0afe92c21815fd4ef3bb7e1e82265bc8
BLAKE2b-256 6fc63fe4037c067b45eebb8ed4572d979daeaf2aef72482710d1ce6bbf60fee4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 30550cb98ce0ca2c51bd7cdf249f9f317175e504f9f872513412a4fe0326fed6
MD5 6b40979fa362f28122ebd24dde7d57e7
BLAKE2b-256 1259c309e1276347e02258de889e8105f967b5e56433e762b952ac0bbccc8899

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 458df3278f69d14a326687954d06dbc0ad1af83c82aedb719f3d00e0af9be62f
MD5 4cc033a2ecacfc78a39a8b82d1c56c84
BLAKE2b-256 4c8346a61892d6d0916349883a363974674982a7ad10778f2737dff05f022605

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 26168eeb967ff7ed233917a13f15207498d5e030d22e0daeb355092758337784
MD5 829cfb6bd089cb31a4786fcf2b553bb3
BLAKE2b-256 7ca70ee187912f03216d73736e81f04c46035c7a9dc0c62a918bda40e9f06d07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4e1997b74bd174e6ae845fbe3db8e62fe566de7d774cf0eaa16cd7ee61eb9425
MD5 b23e69124a651d60870f4655603a444e
BLAKE2b-256 4053c16a18f7fd448562c6b3c6659c0670af337a0c7c6b130cd7e9b2d761b3b2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fd6d0dcd06e0d674e0799a08578343318af0de41c484ed4d0507844584b96d7e
MD5 ccbb2f3e3ba3678b9872936bc9692d22
BLAKE2b-256 24ee82828d1c1f4b7522f10ddc178c53babdce6d102edb7acdea77dac9512309

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 9a727a0b987ba11d2b7fdba41931d5dbdecc27199d7b5d38f2e7d987e872dda4
MD5 5f1916266311ad2218647fd457ce1b04
BLAKE2b-256 cc9e4b3f7c6e9fe6d0a1fe24de60bad7a2a31d1571a9e1b49b8ac0dd965a219c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 207e22fc4eb13bc0e199b9780ef2d89da9f83df0b69e55e1d01e8147936fdb5e
MD5 8021e477694d02c94ba5e66346f82c43
BLAKE2b-256 1f3f7cddc8d390b8fb97022c297fd6cad3e9721c73df2431684046dfc676d987

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 86361d7f1d05a14125c1bd6270691cf96f76d51c2606f94a73ed8e0bcd5b4341
MD5 2ad1b847a0b31f11dea550f4f5403572
BLAKE2b-256 cd7f06dd1f7f36f0bbe41a81e9c415d1c5554c7606fce9ccb214852f23321c0a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 16884cf64509454943ab33bfd8152112dd8ffc40279c95c8265ab617c0b4474e
MD5 4429b62daef5b0c1a7bb6e10d8a3ec6d
BLAKE2b-256 d0f42803f1257f48aa35c7a0722bd32d27ada758793230e4a4de23f0816c327d

See more details on using hashes here.

File details

Details for the file stringzilla-3.5.0-cp36-cp36m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for stringzilla-3.5.0-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 7b49f5782d5ba48b45a56cdff77070be8c060b891a535c1073cc62a4ba7a3b51
MD5 0ee0a026c645bf517e8ec43585bc505d
BLAKE2b-256 75d2a0b1c482e3b046ee767654850ecb2f22d251813d4e9a121b68d7723ef59b

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