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
split lines separated by \n or \r 2
strcspn 1
x86: 5.42 · arm: 2.19 GB/s
.find_first_of
x86: 0.59 · arm: 0.46 GB/s
re.finditer
x86: 0.06 · arm: 0.02 GB/s
sz_find_charset
x86: 4.08 · arm: 3.22 GB/s
find the last occurrence of any of 6 whitespaces 2
.find_last_of
x86: 0.25 · arm: 0.25 GB/s
sz_rfind_charset
x86: 0.43 · arm: 0.23 GB/s
Random string from a given alphabet, 20 bytes long 5
rand() % n
x86: 18.0 · arm: 9.4 MB/s
uniform_int_distribution
x86: 47.2 · arm: 20.4 MB/s
join(random.choices(...))
x86: 13.3 · arm: 5.9 MB/s
sz_generate
x86: 56.2 · arm: 25.8 MB/s
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. 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, \v, \f, \r, \x1c, \x1d, \x1e, \x85, avoiding two-byte-long runes.

Character Set Operations

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

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

Collection-Level Operations

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

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

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

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

Iterators and Memory Efficiency

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

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

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

import stringzilla as sz
%load_ext memory_profiler

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

Low-Level Python API

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

import stringzilla as sz

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

Edit Distances

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

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

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

import numpy as np
import stringzilla as sz

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

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

Using the same proteins as for Levenshtein distance benchmarks:

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

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

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

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

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

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

Serialization

Filesystem

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

web_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 import foreign_buffer
from stringzilla import Str

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

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

Quick Start: C/C++ 🛠️

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

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

Or using a pure CMake approach:

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

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

Basic Usage with C 99 and Newer

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

#include <stringzilla/stringzilla.h>

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

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

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

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

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

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

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

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

Basic Usage with C++ 11 and Newer

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

#include <stringzilla/stringzilla.hpp>

namespace sz = ashvardanian::stringzilla;

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

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

haystack.end() - haystack.begin() == haystack.size(); // Or `rbegin`, `rend`
haystack.find_first_of(" \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

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

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

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

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

Sorting in C and C++

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

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

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

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

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

Standard C++ Containers with String Keys

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

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

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

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

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

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

Compilation Settings and Debugging

SZ_DEBUG:

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

SZ_USE_X86_AVX512, SZ_USE_X86_AVX2, SZ_USE_ARM_NEON:

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

SZ_DYNAMIC_DISPATCH:

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

SZ_USE_MISALIGNED_LOADS:

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

SZ_AVOID_LIBC and SZ_OVERRIDE_LIBC:

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

SZ_AVOID_STL and SZ_SAFETY_OVER_COMPATIBILITY:

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

STRINGZILLA_BUILD_SHARED, STRINGZILLA_BUILD_TEST, STRINGZILLA_BUILD_BENCHMARK, STRINGZILLA_TARGET_ARCH for CMake users:

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

Quick Start: Rust 🦀

StringZilla is available as a Rust crate. 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.6.7-cp312-cp312-win_arm64.whl (61.7 kB view details)

Uploaded CPython 3.12 Windows ARM64

stringzilla-3.6.7-cp312-cp312-win_amd64.whl (67.6 kB view details)

Uploaded CPython 3.12 Windows x86-64

stringzilla-3.6.7-cp312-cp312-win32.whl (62.5 kB view details)

Uploaded CPython 3.12 Windows x86

stringzilla-3.6.7-cp312-cp312-musllinux_1_2_x86_64.whl (249.2 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ x86-64

stringzilla-3.6.7-cp312-cp312-musllinux_1_2_s390x.whl (175.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp312-cp312-musllinux_1_2_ppc64le.whl (209.8 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp312-cp312-musllinux_1_2_i686.whl (191.1 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp312-cp312-musllinux_1_2_aarch64.whl (185.5 kB view details)

Uploaded CPython 3.12 musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (254.5 kB view details)

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

stringzilla-3.6.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (186.0 kB view details)

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

stringzilla-3.6.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.6 kB view details)

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

stringzilla-3.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.8 kB view details)

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

stringzilla-3.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (192.3 kB view details)

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

stringzilla-3.6.7-cp312-cp312-macosx_11_0_arm64.whl (70.2 kB view details)

Uploaded CPython 3.12 macOS 11.0+ ARM64

stringzilla-3.6.7-cp312-cp312-macosx_10_9_x86_64.whl (73.0 kB view details)

Uploaded CPython 3.12 macOS 10.9+ x86-64

stringzilla-3.6.7-cp312-cp312-macosx_10_9_universal2.whl (110.9 kB view details)

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

stringzilla-3.6.7-cp311-cp311-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.11 Windows ARM64

stringzilla-3.6.7-cp311-cp311-win_amd64.whl (67.4 kB view details)

Uploaded CPython 3.11 Windows x86-64

stringzilla-3.6.7-cp311-cp311-win32.whl (62.4 kB view details)

Uploaded CPython 3.11 Windows x86

stringzilla-3.6.7-cp311-cp311-musllinux_1_2_x86_64.whl (248.5 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ x86-64

stringzilla-3.6.7-cp311-cp311-musllinux_1_2_s390x.whl (174.8 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp311-cp311-musllinux_1_2_ppc64le.whl (209.8 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp311-cp311-musllinux_1_2_i686.whl (190.7 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp311-cp311-musllinux_1_2_aarch64.whl (185.6 kB view details)

Uploaded CPython 3.11 musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (253.4 kB view details)

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

stringzilla-3.6.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (185.5 kB view details)

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

stringzilla-3.6.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (213.5 kB view details)

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

stringzilla-3.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (188.9 kB view details)

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

stringzilla-3.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (191.8 kB view details)

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

stringzilla-3.6.7-cp311-cp311-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.11 macOS 11.0+ ARM64

stringzilla-3.6.7-cp311-cp311-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.11 macOS 10.9+ x86-64

stringzilla-3.6.7-cp311-cp311-macosx_10_9_universal2.whl (110.7 kB view details)

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

stringzilla-3.6.7-cp310-cp310-win_arm64.whl (60.6 kB view details)

Uploaded CPython 3.10 Windows ARM64

stringzilla-3.6.7-cp310-cp310-win_amd64.whl (65.7 kB view details)

Uploaded CPython 3.10 Windows x86-64

stringzilla-3.6.7-cp310-cp310-win32.whl (62.4 kB view details)

Uploaded CPython 3.10 Windows x86

stringzilla-3.6.7-cp310-cp310-musllinux_1_2_x86_64.whl (246.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ x86-64

stringzilla-3.6.7-cp310-cp310-musllinux_1_2_s390x.whl (172.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp310-cp310-musllinux_1_2_ppc64le.whl (207.9 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp310-cp310-musllinux_1_2_i686.whl (189.1 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp310-cp310-musllinux_1_2_aarch64.whl (184.0 kB view details)

Uploaded CPython 3.10 musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (251.8 kB view details)

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

stringzilla-3.6.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (183.9 kB view details)

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

stringzilla-3.6.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (211.6 kB view details)

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

stringzilla-3.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (187.3 kB view details)

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

stringzilla-3.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (190.2 kB view details)

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

stringzilla-3.6.7-cp310-cp310-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.10 macOS 11.0+ ARM64

stringzilla-3.6.7-cp310-cp310-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

stringzilla-3.6.7-cp310-cp310-macosx_10_9_universal2.whl (110.7 kB view details)

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

stringzilla-3.6.7-cp39-cp39-win_arm64.whl (61.8 kB view details)

Uploaded CPython 3.9 Windows ARM64

stringzilla-3.6.7-cp39-cp39-win_amd64.whl (67.6 kB view details)

Uploaded CPython 3.9 Windows x86-64

stringzilla-3.6.7-cp39-cp39-win32.whl (62.4 kB view details)

Uploaded CPython 3.9 Windows x86

stringzilla-3.6.7-cp39-cp39-musllinux_1_2_x86_64.whl (245.6 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ x86-64

stringzilla-3.6.7-cp39-cp39-musllinux_1_2_s390x.whl (172.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp39-cp39-musllinux_1_2_ppc64le.whl (206.5 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp39-cp39-musllinux_1_2_i686.whl (188.0 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp39-cp39-musllinux_1_2_aarch64.whl (182.9 kB view details)

Uploaded CPython 3.9 musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (250.5 kB view details)

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

stringzilla-3.6.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (182.9 kB view details)

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

stringzilla-3.6.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (210.2 kB view details)

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

stringzilla-3.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (186.1 kB view details)

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

stringzilla-3.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.9 kB view details)

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

stringzilla-3.6.7-cp39-cp39-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.9 macOS 11.0+ ARM64

stringzilla-3.6.7-cp39-cp39-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

stringzilla-3.6.7-cp39-cp39-macosx_10_9_universal2.whl (110.6 kB view details)

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

stringzilla-3.6.7-cp38-cp38-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.8 Windows x86-64

stringzilla-3.6.7-cp38-cp38-win32.whl (62.4 kB view details)

Uploaded CPython 3.8 Windows x86

stringzilla-3.6.7-cp38-cp38-musllinux_1_2_x86_64.whl (244.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ x86-64

stringzilla-3.6.7-cp38-cp38-musllinux_1_2_s390x.whl (170.9 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp38-cp38-musllinux_1_2_ppc64le.whl (205.6 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp38-cp38-musllinux_1_2_i686.whl (187.4 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp38-cp38-musllinux_1_2_aarch64.whl (182.0 kB view details)

Uploaded CPython 3.8 musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (249.6 kB view details)

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

stringzilla-3.6.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (182.1 kB view details)

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

stringzilla-3.6.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (209.3 kB view details)

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

stringzilla-3.6.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (185.1 kB view details)

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

stringzilla-3.6.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (188.0 kB view details)

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

stringzilla-3.6.7-cp38-cp38-macosx_11_0_arm64.whl (70.1 kB view details)

Uploaded CPython 3.8 macOS 11.0+ ARM64

stringzilla-3.6.7-cp38-cp38-macosx_10_9_x86_64.whl (72.9 kB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

stringzilla-3.6.7-cp38-cp38-macosx_10_9_universal2.whl (110.6 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.7m Windows x86-64

stringzilla-3.6.7-cp37-cp37m-win32.whl (62.4 kB view details)

Uploaded CPython 3.7m Windows x86

stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_x86_64.whl (242.5 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_s390x.whl (168.3 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_ppc64le.whl (202.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_i686.whl (184.7 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_aarch64.whl (178.6 kB view details)

Uploaded CPython 3.7m musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (247.1 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (179.2 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (206.4 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (182.0 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (185.0 kB view details)

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

stringzilla-3.6.7-cp37-cp37m-macosx_10_9_x86_64.whl (72.8 kB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

stringzilla-3.6.7-cp36-cp36m-win_amd64.whl (65.8 kB view details)

Uploaded CPython 3.6m Windows x86-64

stringzilla-3.6.7-cp36-cp36m-win32.whl (62.4 kB view details)

Uploaded CPython 3.6m Windows x86

stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_x86_64.whl (242.7 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_s390x.whl (168.5 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ s390x

stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_ppc64le.whl (203.2 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ppc64le

stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_i686.whl (185.1 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ i686

stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_aarch64.whl (178.9 kB view details)

Uploaded CPython 3.6m musllinux: musl 1.2+ ARM64

stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (246.9 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl (179.3 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl (207.0 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl (182.1 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (185.4 kB view details)

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

stringzilla-3.6.7-cp36-cp36m-macosx_10_9_x86_64.whl (72.6 kB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-win_arm64.whl
Algorithm Hash digest
SHA256 0e60c3cff0fac22c10239bc39b4e3f02dfb6050fdede9486b2f18472f168fe14
MD5 e3b76c62480bb58fa16950cc1804c990
BLAKE2b-256 616535edff7709a8483ca6172270e4effa293ecbb656613ae05643408c6bf864

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e85011e408870dbb1a80479543ee76c979f2cbf55a16db0add2b34093a533c83
MD5 70d48e9d277aa7d01017aecbd6e2c2f1
BLAKE2b-256 59a59e60be9d86796655858998bebebb4b43ee3f3d20a360fa1b8bdc63d845aa

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp312-cp312-win32.whl
  • Upload date:
  • Size: 62.5 kB
  • Tags: CPython 3.12, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-win32.whl
Algorithm Hash digest
SHA256 065f3ec8e5411b17faa60c36a3ea76b5ad9b99a0c2482f61d1fd398e355e31a6
MD5 9fe76c8de172313f2a663972bb098f23
BLAKE2b-256 3911406f3ebe04111eaaae11f8e0d25ce51e83a5ef4ea2e600f2c8650d7b7a5f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 54c01dc011ffc4a107efab66a0144f758bc2318f680205206002393bec41788a
MD5 caa807525d7fdddd50bfdfc28ce9739e
BLAKE2b-256 3cb06fa93408405cb011dc2b5be471db18b185198ee4522308f7dac01072730c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 3d5286707ced7d9b952828a602fbafcc8651a8275f8e1af649674caf37eb025a
MD5 6c6e8023e069610af6b924fe238fbdf0
BLAKE2b-256 782eb3c8b04fb1de1630c2bcd74f262cb6170284cea1502c7260f78ffc334ed1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 ed28e495b786e576371480241ad55aff1f033e81ea26e02c0effea82b980d5bd
MD5 6f64382bca75a4deaeb75f090cc83ae5
BLAKE2b-256 13194c33bd1b5c55f4541319f0d837053f2f55199fc67a1e0c9815480528073f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 8e52e5bfc6f259f04387f8cd341bd154a7716894c825c21891d687f62fb72c62
MD5 e3d559a11a85c2602786eaae413c9308
BLAKE2b-256 a45be2674c03c65b77b5d9867c6313fa3d2137a63e2c78a1707794f065054a55

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b2e58f0353a62fe2fa52c2552486c3b2f7880f1e209d0a8ad03ab9cb32230ccf
MD5 d839c5631f98c32cce00acba47b66e76
BLAKE2b-256 da5a3e2df525450fc1f926d13f717f2419b8c5c8444afef577f0187d032f8208

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8d66b1375e3416c1d2b794ee67031203a3a404dc146b86b463395e482b3dbdd3
MD5 71c55ab2288c2bb7ba543d2889ac20f8
BLAKE2b-256 4efdcd06b9dfa582d9d75cbddee68d6260ab2b0cba8a9e611305f08a785b91cb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 10afeb18ca83a52f0ccaba0c1332fdd11c399b7f63e920ef53b00f28ab070def
MD5 f349391e8b7434edb65c4c96c760aad3
BLAKE2b-256 6e27025e10512082bb9af94b1869d5a3d5d9cec0b20f0d42a54000d118f3281b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 071a48ea07d74c4a798a2798f98d8980187cda88649a08d16ad33c7f43b201d5
MD5 c83cd7f01f652c0d534c32d6ced0d596
BLAKE2b-256 12747f19e6159297c4d2b6725eab762ce61e3a959e6b8e65b34adf1af14e2967

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c617a9fb1db35b6714ff66403f12de1dd37d376c6b763534cfaf6ef1ee86936d
MD5 b44e8f3a81021f23fec6101ca45dc3c2
BLAKE2b-256 5fc1f70d62dbaa0690ea22e9b27c3be66debad11e4c3ef4e333058278c3bface

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 2384245c2246b882eae4e84756e2650683b4a07dc28b9b46055a516f94313cc2
MD5 4daed122bc4411a16709ea7cac6391f8
BLAKE2b-256 c89122f81ecc6bee7a7e0aae02931771966c2b809c3cc66b71e8396c7815db2e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 61394d3552685fb9ea15a91c1a52a72168e25ba71fdb418beb3208707c37437f
MD5 d44d82ed24cc4d1a89533e576def00f5
BLAKE2b-256 54de67599a799b1c9f2db3805e49a275ea7ed39c4c640d4202cf1eb3b165ca5a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 a7f8a8de7fb70e4c29ff97de4e57b86c9e83a6489a1365108122f64f169b2950
MD5 8e7fc8005d7ad79e27b41b1b2f09e904
BLAKE2b-256 b630dac8420003c7364226f58fc7d9b4d18fbf6a69d1d74b782fb83f1011abec

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp312-cp312-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 45a7aeb13120e912cd8b906f97aac029d8a71c32c5e50f1c9947ed58f1a20665
MD5 61f8804717a1b5d90262d55405c5a4f7
BLAKE2b-256 d7c1a74ad5f56f29901be3c0bf93736fb40c2ea654adfb6bf970a10cf22a863c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-win_arm64.whl
Algorithm Hash digest
SHA256 8ca6f08e1232a4051417e73ae38114fbfffa66349483e44bf3f17f3c3cd06461
MD5 28ed80249b759870df7a54bc0ac69250
BLAKE2b-256 9241f7fea1cc4a56e42957e2a066842eb2317731400dc3666eb94b28cad3f61d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 ca632294ce1d8b7bc08805c409555dd111ed372feecdda26e77a97b937c7a50a
MD5 7c4b435b77c4315ae12e7853890eacf0
BLAKE2b-256 34d85dbdbdb42dbf2a80794f76cfe1bf8d941ff16274af3b63508bd7be4ca13d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp311-cp311-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.11, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-win32.whl
Algorithm Hash digest
SHA256 593e74ac7b86415b240616d0a9d07912c349ba0979d1151c41a77fef5b264ec0
MD5 89febb7c2312ce9810a046829c574c21
BLAKE2b-256 30ca4a2797c18328256212e6fc6da90fe37b33e28cbc0a971aa9cf970a6f0688

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 59b290367e859aec0b3a39a874085d35fd852491ced66c64962aad0a2b03f43d
MD5 26e4d1d910cb73b7fab126d88acb1143
BLAKE2b-256 9080ef7a9ecc0801344d9d764eff22bdb79ac82168e47c43a1b61fd52439a90e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 4cf8c03e87e1669a996409b34a330f16e670670d50bd82e85f7b3e20caacf97c
MD5 f1ea31e8efdfe6dbc9b3913bbecc263d
BLAKE2b-256 600a5abb1c5cdf9961861ab91ca0b1e9cb7c19ad993051e7a7160fbb715eab40

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 b4d0a116149831b76ef7142c9fa6a339de1b2bfb63e10a3987ef49adeee303ed
MD5 1a297db38b818987780e477e652a6a9c
BLAKE2b-256 355c23215772127d0bbcc5b333922dc230781a12facf1e586eff42817c869385

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 67c873e5cb2daf73cab04470f66dbf43b24cedac63281115be3180fac8206494
MD5 336c238babeb456473ad6cf84fc4e1d3
BLAKE2b-256 938261462e1d35fd46429d8807b1a871cc2388bb98f7eb4d4f4e8d6c75d2966e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 5a73280527683010f63f73504057086bdb5c0f53b1fa181b6555e21708b24640
MD5 c9166f11a6bc2b35363b2f08e316feda
BLAKE2b-256 b6d4ce241d7ae6d186ab7a3cb38cbf4a98abae19d6b0330d6162ed12e36713ae

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7431f523d5f17d125798e8a8b54b3a2ec4404d4e88db862018919022efeabd61
MD5 6ab24382cf77977109e8f3969217dd43
BLAKE2b-256 58bdb5fc23e67a6043fd44ba509c5e3d8ea10605d494b0c8cf1507f1e7e03015

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 5edccbc2b322b3c7fb26ce8a0bda5c96a79e4f343773e3e80240241364272660
MD5 3d51f656bdc29b5da3f2f0b2f25c7090
BLAKE2b-256 b0d806f03dd8aafd1e4920eff7ed9b8af647bace6a252d0441eeab719af02882

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 23f2a858e8e66b1fa1cac22c01f6848932c877abef7dacfd0a09668b781d4991
MD5 daa336a9d542149d70650cc217957c5b
BLAKE2b-256 f4610af763740078b56fea8051f27572574766704e3022b9702a98e744410d94

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f6f442a082991ab974da136825d63c24dfccc8baafde70f13a09368ee16c9f31
MD5 8209a680c1a05e2e598c070cb9ef8d9b
BLAKE2b-256 d66b43a1a8e926347c23081d880618580fa3ec084db558cb511457175286fa54

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 11fb9a1c01e36acbd7dbb3d4a3bfb2060ec058cef5603aebb0406075ba598f16
MD5 26667719c93380862166a7dfce0cc4bd
BLAKE2b-256 1a71f1c949e9c5dbac501e93955bd7355d635f803f49374696087ce0197be88c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 26fbdd95176d1c311de59f799d6c228ea29c116a82438a2dd9227bc2f7fd1227
MD5 6c303dacf0fc340f8ac448e0db80115a
BLAKE2b-256 b65376500c07f600dbc7ca33389ee41eda42919f21a0061b8f572958a1a8825a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 246ac20b3fad36d3539594eb178a30ad236ece844cef9f90c3a17439e5e88d7f
MD5 2791ff12ca7bd2fa3a94a8fd39f639d7
BLAKE2b-256 6d6597e2e264619beaa6aebc6979e43a3a9567db06634ff94840bca79822eeb5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp311-cp311-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b0a2d82cda2ee0a7bf184d79060d5cf24d1df4c330fbc714c8286860a18801a9
MD5 24332c2e4d5409f09b60a2ada7792513
BLAKE2b-256 4f9ab7e0398c022c56ef905607827f48ba7c5231d97563aac8813099805985cf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-win_arm64.whl
Algorithm Hash digest
SHA256 c7870d234de5ea67ad097fd4c3a2b8bc433dfd06807cb924ce18402a639ae8c6
MD5 896ba213d41104ac7e451debdc20cb59
BLAKE2b-256 e8c627ed027612295529a671e46f2ace49c72aca88bff15fe7883a5b8e0bc5fa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 f73a741c7eba3be2680fbc8484b1db42619a161ecd06058ff7e3bea5f03ad07a
MD5 5db96a8e266abc4267d91597cbee3e26
BLAKE2b-256 26c78cd7ebd22d755d071c1cbb2f286cd07cbb07f1bcb7c913a4071597aa9e72

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp310-cp310-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.10, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-win32.whl
Algorithm Hash digest
SHA256 1832869afcc6a64f69afd39d94b0dcf4c1ccb995bdec0d225ee81f12e2dd56a7
MD5 f0ec1794819dbd395d0bee776564ebe2
BLAKE2b-256 8e719db6ec40648fb0e06d6dc0b1b50180b0dd59a617b168752c19d3bf956c9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 45f95cb37bf9d0933ec0492f4537b5fcb518f88cc1bc46c52d95e47bc934e228
MD5 47949ce1e507360511e589b3ed7150b0
BLAKE2b-256 14fb7e5e9a99b9fdcc7e85a67a06245dace13cc537441e1cb0ae3d1e870a9277

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 a8d7ee5200e959375446c2262769946c88d8556281d47a860a28f784d658a52e
MD5 27228c8fd11db0699e1187f65e5721fc
BLAKE2b-256 2e44beee48da5d35dccdf58f3bce9c1e498701b3aba841ac866e423e6b76eb25

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 fdb9c0ff4bff735e1a0eace0271f90579a66c8fe645e24819812c43b4ca9906a
MD5 aebc999f15aea904cffb6e803bccb21f
BLAKE2b-256 fcf8a194c6cd5797ba6149ea50aebe99d86ce8c3376cc7061f63a8e247280111

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 62c5cf5fe46324e5505b13403e25ac3cf77d8b54699138096ec7cfaacaa2818f
MD5 677e7c827545bc0e7612eb651fda8332
BLAKE2b-256 e31fe3316261fa9675e49b5ed3f0b04b9c230cd174d10a6ad0832f24aaf95af0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 e26c0a76fcb74e4743279e055fd50cf4894c00951a03136530a7a00ff822faa0
MD5 b24051c7029f4512994dcf6fbbe25f69
BLAKE2b-256 4748fc91fb23cb71d645ae90f1ea48c83365eedd29e24bbd97057d3a29f2c87e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 aef69c8454a13833db04af5e11976a217d8255a3113b4430ae5f7f66a243cb5d
MD5 7256b35747a43143b22d3c3775bc9b14
BLAKE2b-256 7d0f42210317bdc581705eff9838fb5ee92785c975b97d58f15a5d1661eec3c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 3f3c875c29c5207bf84cc4af7f5bd8856f31d43c100f3885aae3e7761f8be7f2
MD5 123b64c52e1a5e3cd47393766d6a885d
BLAKE2b-256 bdf493135382ca954c038fd48ad556df065c2f6179739eb520b6f76e061691b3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1d1da2a8cbdf6ff3efadc2fa4c338dbdb901e24f5348493faa53ebcd28dfbfd9
MD5 29a12baa7c6a314aaa59e83d1a2cfc3d
BLAKE2b-256 41de3e37aaf6d9513c0cf8f3bc20ff06a5ad87c2cb6ad8358642b2d5612f73fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 469e0781bd55985d0f9daec5ee15360544aa29ebdf90a99d249aa8344187cfcf
MD5 7bdfabfc3394c0e9b59e8a4885bfbfa4
BLAKE2b-256 02d202548f200cdbe046572912c4dd8341a4d04bd8a1491563a8384fc658f331

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 1dd434f7522aae92eb941822d55ca5d3e33e0a4aae36bd3039ba4aaa80a1a885
MD5 5c38dc6fd4d5e1951d74d46c71082caa
BLAKE2b-256 e855f73a6027d1470904b7e0e87beab2eb6be51b1148d08691fc627e1365fb9d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a9112c37584244072362fddeeeb141c830d16725b463bf28a98f65f6bb020e6
MD5 4d2e5ddf94a2b5f44aff7e76dbfb9696
BLAKE2b-256 097691449b32f1e1461b75d4e1db5259fa5a033f7e0978f3534a0a55d9777e4d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 96c5d5b9c302054152c557e710d22f2c749542ae386f4034f6d4a605b12f0287
MD5 05d5bd65e72372d0f6ea66260a649f60
BLAKE2b-256 7e75ccd93e51e189cfdf8d6c5a0f7d554d8f0932a44b28937833148c9adf8769

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp310-cp310-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 ef15ff0283f079a516528b62a4ec02fe0342ad9353faa7eba490e078cae334a7
MD5 b1e4e9140bfa20ad78768ba0efa36801
BLAKE2b-256 2daa803481d1d2b856b57f2e67bb097592f436a179ff411809968770669acb7e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-win_arm64.whl
Algorithm Hash digest
SHA256 2adb8d55881db636ae1a0e63fdd467c2757b48921d0b069515daca4744bca763
MD5 e0f95007776985715dcdcadfa74b8af9
BLAKE2b-256 cdc6f989b6cb5854b3185064db50ca2362b1fa0bf53180c7fc4cd3f75ff4ba8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 113500fb9ad1c5151e7fa02b0a7972cf3f74e00f9e652427884fc204ca736546
MD5 e05f5853cd38e38c15af314f070a53a0
BLAKE2b-256 e26a8b467fa653b7e0fe932e963eaf5e5808ddb67032ce62a8224ac3baebe1f2

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp39-cp39-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.9, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-win32.whl
Algorithm Hash digest
SHA256 d686910c82bbcd30317d1c849ce67e86864fa6b6d64e5ebd85839f49814bfbb5
MD5 e895ce44366f0dd9ba6a0f002e9e4db1
BLAKE2b-256 2ad5bb6d56310fb4b2380abec57ad97df16fe4bb974056a6c56b8154052d7641

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4eff18e9038ed61965ca35d79da86d6128a6bd61780395cf55a0725911b7b592
MD5 67c4701b9ea0f53ee7311da2466e3f2b
BLAKE2b-256 f5e8f85db6a9790c640e8c5fbb28c673087224f04f740ad33b1cc9298105057e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 08853999091b98ae798d2a9ab4fa84ba5341a27b08299e6e8dc119e5c0d24492
MD5 d090666aeeeb19ef574859c5f13079ce
BLAKE2b-256 49746a4e8e0645de60a7056af10abb9c6ad8216db1672ff82780cb78b6c7df14

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 051d20ae9d2988b2ff92add1e20aee54f0b7196c62cc66569a9edeb833b6f6bc
MD5 3f23497f4d9ab243911188ab50879435
BLAKE2b-256 ca2f9d947e7dd71e6c0e4eac2da4c53173135e31599a004669dcb3add7af560e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 a16ff281eeddb053c3075fda0bc9d4ff44e110d556714ea2f7a9661772cdecea
MD5 d81aace21e2dbbe3521cc43902119db5
BLAKE2b-256 d30f93213822a9bc31b2e8f5693dce81eca93ceba5a4a674d80b209d63115ec8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 49a75b1af0f25ceae03a9e26888657190e8a2778ecfc6d27f5c02e44048d5945
MD5 305b61406cea208452d165bc04375bb1
BLAKE2b-256 3db50adea8fe8197212e2a83e0ea65e3620ef9cfec12285275c6f5c59af2272d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8bb46b28a97f096a3be9f3c9db04e140243c615922515a037098350b243d25c2
MD5 4c2a4c3c5969708f0a28053f2144c158
BLAKE2b-256 f1614644e733107887e39d42c79a29ce532bcc585e15f90ebf976a7c2da0fe96

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 b4f9571bbfec2075b622887ca96bed4d4d5216b417330648a1ab5e83982c5654
MD5 e25c887130c382dccba17c76e3dd415a
BLAKE2b-256 7c21e2036b5b931abd4661d71dfb127b5867f59702748383203fd526d48b8d0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 03d76d03753f632d881a501b23f235c89c63514368c15ae4bdbab44bcdbd0442
MD5 e1f229c1cf977aaf704fe7b229b53251
BLAKE2b-256 be947e351f7444f979efda880449aa443d638c590deb70b85f3694b1dae857b8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 35c6374c4721c9c12b8bf47e4191c2f800ce82a34a306beb4b77bbc16dfd1f0a
MD5 b7a7cdf521f5f5cbad46052959a1e1ab
BLAKE2b-256 fb0e996169d1cca1533b35a61ca07a2d17de1a418e0608bd1cc7d3ef721adf1a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 143398b12bad2da4291d379560058cb81bf8ecd4d9157ddd469f5ae02b53341d
MD5 676a1f811b91064e271dbb27c9c8ec66
BLAKE2b-256 323b7ec087a964be56843e999ce8c7c9c423ec2cee8edc2284aa923932f61f88

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2df3f3efdff849180e15b1c12a0740a1453ec88e3d6a021359a4adde50a27208
MD5 167deed3d443b4deb928f0fc24a10b4e
BLAKE2b-256 b5566f9e745f4af306551ee5dd64e1c27362f84fc1afa85086b21a95871a81b0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 e386c10a6985c175f99e7939433ebd0fadfcae8a4050e460826b0d5f013c2ca3
MD5 a248a6705929ffba84910af3b0ebf040
BLAKE2b-256 2789ba465a5f3f891572d75cccbd005f51f6b59a2397b48faea310ea0c7f03aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp39-cp39-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 753cfe5016789a10c825620d7a0f98a0243abd55566ff9da966d127f9cb6b22d
MD5 fc6cd3df48c24e1ef7fa24dc781c4a08
BLAKE2b-256 095da78631e4f7c337583517d1852e942203e686f5211ea5961a11a8959467cd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 2cbced0eb753c51ded118584109dfcf25756d262644a735c5f880f3ae51d02b3
MD5 3e2d2d969a45ca1f227527d4b7804ad6
BLAKE2b-256 9f89b11a11b749594ba36702f5de02a5f57860b85c8eef1cec3a35dc0ed18262

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp38-cp38-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.8, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-win32.whl
Algorithm Hash digest
SHA256 a0778f3d02c21080fa5251c91c147377778b8de4aa9b14cb76bdd7b5caac1359
MD5 00c2eacb45cac3ac94c97ac8f6242fce
BLAKE2b-256 46a18bb0825f28823c2bc59e751d30e7be89d1daba92ca71b1a14cab842d7750

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cb9495c86c1f03a5f7bbab4c230594e3665d3918ec8a12277740258509062abb
MD5 17c0aef9b1174b53c0c59ad6a0335bc5
BLAKE2b-256 5963ea0b0681be1beb5ebe54111a7bea097426267b77f996309b456d0fc3068c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 bc63e8c447ab9a9a3a3680c110ad20fa5cfaa71610985937e6a6681065d672fe
MD5 98926090342e0d6445b8a1d37dbeb62e
BLAKE2b-256 de5db2c23ca9a6bfa5f2ad6a2bb3c040824cfc3529e61c2233949a7832b69d4e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 8c4a72b48f775307e70643cd6779db4510386a7406851ac81d8a36e2ddcd82ea
MD5 568495e40c1b74c1d4423af98e9f62fd
BLAKE2b-256 e171a63a16beda30ffebc8e2bea21582365ef4f371be350cc36372beb8face08

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 fbb7939d12385e2aebed6a1f870c12b034f3163e4fa0f3d5a38865fc8ca4e364
MD5 74c4d2ab46960efaf040ff827eb3950d
BLAKE2b-256 a25c4d6a03f277c5bbccbb288a34392c8ec93a04e0ec09f094a363575cdd13a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4c2047e38b8c214cbf982bfac2469f166b58231f0892128c761294548b2664a8
MD5 e93d1fc6468abe0e8c495e8726ff9d36
BLAKE2b-256 961a42ae4c83e468c80311a899a61638f8410b1221ca25ee612b29471ae83971

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f328032ec0885006d69c74120f34e0b7997cee4a7474ae79c4eab427c96a613e
MD5 6ef8f090223218ca6cca1b9ce2de3090
BLAKE2b-256 302a64f583566753a7fd48fcd09957d60a311736415940f955dace92c2b8bca8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 a2ec18e8349c75597ca281b9de785589e9fb88ee41035895f5ae82a55fa0ae4f
MD5 47adcc1ce7254c6fc7cf32bfb208f748
BLAKE2b-256 7c73e38b8b704b309818583eeac1c7b3cf3e67826bed22da49f58bda861faffd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 52f4eed93991be86c1ba10f7bc7f0b4259bb60cab1decb52c18c4662d6b57d52
MD5 1d9e087082242fdf22bcdd9d2e98935a
BLAKE2b-256 50dfbd7f00357f088c0976507f68522adff86d7c7cfe22f390277ee3021471dd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b3c8a7835fafc0d182c10b4977440bfccfabd5de24985763f8d56cd12a33d2ba
MD5 97a574ddfee1f7a2714534509b1173bb
BLAKE2b-256 4ba99665646d4e9ad29630420824d7f17f0a03832a38d2243fd7d857da929aa5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 65dcf6d2c9fa5907d94e80236480de7846023d51df02fd14ebbf949e908a3ccd
MD5 199a198b7df915ffd8ea529081357f6f
BLAKE2b-256 d01b7b61f208227edf7393836a6a9049d27b7d00feb5ae60c04d07ac56ad0c09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 778e9ce1bb895148c886a7161b56a8a65a4abb8202432777d0c6e5ba7e92b5df
MD5 29f0377eb3e83cd2baa7440d622ab28d
BLAKE2b-256 33a359429625fe94a4fd7c65aa0a0042f924e880e082cda42997a5db40fe428b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 3a92821d3ade82e2b65b3c7402046f8ac45eeb45bd8dc7a97027d350b4c5fcee
MD5 7c143057c7a9eedfa55a9f65c5d42cc4
BLAKE2b-256 5bbd407507a53b751da5194002cef6de87c9d0d1ac4537ebbfc1f7691e7b3932

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp38-cp38-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 88a5b43ea55a2422df48e1ca74cc2adc29a5de360e8256d2b8f038542790039d
MD5 478739a74d97cbfe5e9523849f95ad90
BLAKE2b-256 cebaae8d00c2652b1319b18e8aaa208d09924fd2252fe48f1cb985c8fca6a672

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 502089f6d27f2c0e95c166d55510daf7094b09df1bef323d03ec0b9df721d54a
MD5 f6c7f7a66c05a1cbe79a280c7560c2fa
BLAKE2b-256 95c2cd247af0ec14da7b415d9f42698eefa5e91938160f286f9744248c3ec903

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 81d074bd41be1b47c6694114b4665822b8a94a8cc55ac8e7a23f710ec785665a
MD5 5bee09a778bcddbe2434d0aa0aa23a72
BLAKE2b-256 01aa908c0520557e902118b46d4371ee584f16b2d7283b24fb2bb10f26724b25

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b1c6d533c549ecdb05ca04bdaa055e4a76c527405d75f46dc56e8287ad28bc8c
MD5 4f22f8ef3e8625f434c031e901ec93cc
BLAKE2b-256 009a8a98e10669ab8f944ed23b4f46690ded8d06c3397e8c2278d4762f4aa248

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 233264095e3acb55440a4cdcbb36450d4d5189ea17e19058eef4c71b1496a3c7
MD5 b20d7790bec2ad6fda1125fa4312b451
BLAKE2b-256 eeb01c83bbe78da4aa77731c3aa7eca0a1599d4239c277a904be222ea6659480

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 6f4ca7308168f23d887b7d32e0502a85d60948655c2a7cb5bb9bbf20f0756745
MD5 4ae9ab34a2423f25d04ce0f20a094bd8
BLAKE2b-256 05fed75bfc9fe5e15bbdf8749c80b3dc68ca856ba58a36c33bdb1d7e889f5da9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 c89475785d7c13c578f14e9a7ecd426c6e7b3cc40239dac5fef900077c89006f
MD5 bafe6fd7bcb9276863c11216be063688
BLAKE2b-256 70c71b79b23375e3a98ce47a3507838d3902f9664e5c4ef90c6e833ab97e7adc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d41fb7bdcfbae93e0d0396e64af70bd71d2c4ea67c8fc871722818b86aa8aeb2
MD5 60f4304561d4a6580d3f12844cf1419a
BLAKE2b-256 88b2c1001d9a8ec9dcc46ffe8a680026376e4d183f934fdefe37a74af491e0c6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 40fe3b768a0f9743a01ed20eb2b1174dcc4da08296a2bc12e95641d2382dfada
MD5 1963b91f2fb6e6bcc52adfc780079c7d
BLAKE2b-256 b521527854da9777458f2a2933307af5dfb3374d30b7e06b13a0fde6573b3470

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 697b826839f1d1deff4da651daf4fbf35721c2b754bef5bd880165434886133b
MD5 15fbb9c6c321cda17d29b2125b14c7b5
BLAKE2b-256 07183f095ee5594745dde8377f122388431a86560d6cc08ff59ce14fd5fad380

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 9565ab7272547df67ed59d82a015c99a3fedcdc5a65f4e177fccec668988c020
MD5 0a41da3079e5a387f5dfac486b48b135
BLAKE2b-256 f36fb9b496dd28e209ec365c978ae377c0e6445ca0edc7f4c53179e6a623c5e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3bd29dafd009e0005e16971fce6da9e3e6251f88be40e08a67e389441a6a00ae
MD5 3ba7509b62da00365092703f68884649
BLAKE2b-256 8135c25ccf495254ad963e59a1c20d12e4bb89cccf67a2b0891c491d0b7224f8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 3444d76e5f23d62b5b01756a79bacb11d186bbc7e81a83f29344166abc48b9ac
MD5 8048c404c59aa6346c7e7c1da24d920c
BLAKE2b-256 4aa651633fb0233f93fc47ad971075fa7c478dae10006aca88b17cd168c54f3e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 12d2b8235cd07adc0f9a0489973ec721a4f5a5a3e3e17143c308cfda8b4ae3ad
MD5 ff05ea5b708dd1a6507a6664f8b08c71
BLAKE2b-256 0ad79c3ede888cd28d451a9cef6c063e2aaad1b32820b669712e48662f3547b6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 6172156f849a32e4bc94d36850227ed6322eb037ca6d62d321fce341c7e2ab3b
MD5 2c78a0f99af7a14168f1c3bba9df2636
BLAKE2b-256 9ca8cb7379e15edab9cf2d1a7b062cb3c2f0c47759baf4bb0fcb4388db5f5f6d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stringzilla-3.6.7-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.6m, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.0.0 CPython/3.12.2

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 da8a268694e381b04cb4b6f15e92389435c05e62b41bbf232cd89c5533951c4c
MD5 e57d44a6812654cd60eed4ff61765eb1
BLAKE2b-256 7f087488dc600095b7488f4239cb6aa7fc09492725441d4c5ed3b3bd01cdf974

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a6d5ee69415508982f2c498e0d76476cd942845ab0ecfc734abfc1c30a949da2
MD5 4e5bfda6d98d74f2dffd981f6af4dfd0
BLAKE2b-256 1bd4ce33949c17a3092b74fd0999c9e576c624bfe6cab05436fe53548ab8cfa5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 94f5b86bd11e109a280e97236c361e487dd5cecb90db8309a17919eb7ae62edb
MD5 4505256b53243770b27982c71af0ae99
BLAKE2b-256 724d3eafcbe1896b23a95d8574f0b2d681c497be612329c90a7046625e13fc68

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 00607afbf81b04962c3b31770e4c4d2418ec96e9d3bb09813fb43f2a7d65fdef
MD5 19ce8e2076fc554cd6340d0410ee64f3
BLAKE2b-256 c01fec6d3aceb360773dea0795b0cd019f6a653dac479038440a0cfa09114b10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 ec87c2678ce4f923e8c1ddb9764271c038553e29cf19c4f76eae18ad701ebe9e
MD5 57e4215603f8b8dea96b7556f197d009
BLAKE2b-256 b80ab129e90482a477d57f619875ad432c179ead76dd978ea4ca93d538589aa1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b1acd207389e44a1d0ec12cc0adeb6a5b0367e620d727557f0e65b889fcf6239
MD5 b6c984ce98545f65f8d5c381aced7745
BLAKE2b-256 6e176c59713f53f2c126df44d19895215bc8d5f5d50a6185a4d9dc048a7985e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 eb6e5bef424614e14a543034d5a1d8dff0d8b8a2314b7e9e6a15e7762ca44327
MD5 43b67825a2e0d8949bc8242e20580c48
BLAKE2b-256 462f33c48ac9e70e994d278fe48c5b0b93bdaf42fee75c3f20f26a3a6b1c1234

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 70f408acad3ed557d08796b088a7646024454d2dcbf0d43b99bb52d603e0e589
MD5 319b6db28dd6c94f9f1830be5dcc7b22
BLAKE2b-256 53338019e40591b0a7e574306c7b6b323c563a12c35df05c6a85414578f1b9ad

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1c14fe6473bafd2b1f45f9b66e7a006e7908d654314c04bf823ea836454636a1
MD5 196322d63ef135821fcfc21cb87c0c9a
BLAKE2b-256 2dcf66c009ec3c0769b20b52f1801b464c14988aa12a4cd57d9afa6552483327

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5bab52f81ddbac826a37772d55cc3939bdba0ca536419bcf7bd01717b5857c0b
MD5 da316e7a9c96ce76224438acf669a417
BLAKE2b-256 cac088825cfc1d80f1186bc223a569fa60f994fbc812959f85790637f766ea99

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 e8499edb918807ccc34f20cfee27e12c298459db609670a60e065a3c83e4fada
MD5 4c7d83a6eaff850ec25eaa4d0e155860
BLAKE2b-256 cf0c87359481ced21d9f0dddd4581f3bc80232a55bd3e4c8e1de7eef4e18e97c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for stringzilla-3.6.7-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 83b713019797f3bebd9f8cd5e4a95c8d18384020f2659f63fa131dbaf04d8125
MD5 006920173c292e66a57e2997062a299c
BLAKE2b-256 7d015f0019490685ba6d4ec915f260f2f4eaa6c1d7adae3097ae1d01498c937a

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