CH-J Toolsupravljanje strežnikov prek SSH
Meni
Objavljen vir

CH-J Tools

Brskajte po imenikih in datotekah za določeno izdajo programa.

Prenos vir ZIP
CH-J / Server Manager 1704 datoteke
0.1.2-beta Dodano: · Zgrajena:
portable.rs Dodano: Datum, ki ni zabeležen 8,9 KB · 290 vrstice
Oznaka Prenesi datoteko
1//! Small streaming hashes ported from `hashing/portableHashes.js` (MurmurHash3, SipHash-2-4,
2//! FNV). Output byte order matches 0.1.0 (big-endian integers).
4/// Block buffer shared by the block-based hashes.
5struct Blocks<const N: usize> {
6 tail: [u8; N],
7 used: usize,
8 length: u64,
9}
11impl<const N: usize> Blocks<N> {
12 fn new() -> Self {
13 Self { tail: [0; N], used: 0, length: 0 }
14 }
16 fn feed(&mut self, mut input: &[u8], mut block: impl FnMut(&[u8; N])) {
17 self.length = self.length.wrapping_add(input.len() as u64);
18 if self.used > 0 {
19 let take = (N - self.used).min(input.len());
20 self.tail[self.used..self.used + take].copy_from_slice(&input[..take]);
21 self.used += take;
22 input = &input[take..];
23 if self.used < N {
24 return;
25 }
26 let full = self.tail;
27 block(&full);
28 self.used = 0;
29 }
30 let mut chunks = input.chunks_exact(N);
31 for chunk in &mut chunks {
32 block(chunk.try_into().unwrap());
33 }
34 let rest = chunks.remainder();
35 self.tail[..rest.len()].copy_from_slice(rest);
36 self.used = rest.len();
37 }
39 fn tail(&self) -> &[u8] {
40 &self.tail[..self.used]
41 }
44fn fmix32(mut h: u32) -> u32 {
45 h ^= h >> 16;
46 h = h.wrapping_mul(0x85ebca6b);
47 h ^= h >> 13;
48 h = h.wrapping_mul(0xc2b2ae35);
49 h ^ (h >> 16)
52fn fmix64(mut k: u64) -> u64 {
53 k ^= k >> 33;
54 k = k.wrapping_mul(0xff51afd7ed558ccd);
55 k ^= k >> 33;
56 k = k.wrapping_mul(0xc4ceb9fe1a85ec53);
57 k ^ (k >> 33)
60fn le32(b: &[u8]) -> u32 {
61 u32::from_le_bytes(b[..4].try_into().unwrap())
63fn le64(b: &[u8]) -> u64 {
64 u64::from_le_bytes(b[..8].try_into().unwrap())
67pub struct Murmur32 {
68 blocks: Blocks<4>,
69 h1: u32,
72impl Murmur32 {
73 pub fn new(seed: u32) -> Self {
74 Self { blocks: Blocks::new(), h1: seed }
75 }
76 pub fn update(&mut self, input: &[u8]) {
77 let h1 = &mut self.h1;
78 self.blocks.feed(input, |b| {
79 let k1 = le32(b).wrapping_mul(0xcc9e2d51).rotate_left(15).wrapping_mul(0x1b873593);
80 *h1 ^= k1;
81 *h1 = h1.rotate_left(13).wrapping_mul(5).wrapping_add(0xe6546b64);
82 });
83 }
84 pub fn finish(mut self) -> Vec<u8> {
85 let tail = self.blocks.tail();
86 let mut k1 = 0u32;
87 for (i, byte) in tail.iter().enumerate() {
88 k1 ^= (*byte as u32) << (i * 8);
89 }
90 if !tail.is_empty() {
91 self.h1 ^= k1.wrapping_mul(0xcc9e2d51).rotate_left(15).wrapping_mul(0x1b873593);
92 }
93 fmix32(self.h1 ^ self.blocks.length as u32).to_be_bytes().to_vec()
94 }
97pub struct Murmur128x86 {
98 blocks: Blocks<16>,
99 h: [u32; 4],
102const X86_C: [u32; 4] = [0x239b961b, 0xab0e9789, 0x38b34ae5, 0xa1e38b93];
104impl Murmur128x86 {
105 pub fn new(seed: u32) -> Self {
106 Self { blocks: Blocks::new(), h: [seed; 4] }
107 }
108 fn mix(k: u32, i: usize) -> u32 {
109 let rot = [15, 16, 17, 18][i];
110 k.wrapping_mul(X86_C[i]).rotate_left(rot).wrapping_mul(X86_C[(i + 1) % 4])
111 }
112 pub fn update(&mut self, input: &[u8]) {
113 let h = &mut self.h;
114 self.blocks.feed(input, |b| {
115 let rots = [19, 17, 15, 13];
116 let adds = [0x561ccd1b, 0x0bcaa747, 0x96cd1c35, 0x32ac3b17];
117 for i in 0..4 {
118 h[i] ^= Self::mix(le32(&b[i * 4..]), i);
119 h[i] = h[i].rotate_left(rots[i]).wrapping_add(h[(i + 1) % 4]);
120 h[i] = h[i].wrapping_mul(5).wrapping_add(adds[i]);
121 }
122 });
123 }
124 pub fn finish(mut self) -> Vec<u8> {
125 let tail = self.blocks.tail().to_vec();
126 let mut k = [0u32; 4];
127 for (i, byte) in tail.iter().enumerate() {
128 k[i / 4] ^= (*byte as u32) << ((i % 4) * 8);
129 }
130 for i in (0..4).rev() {
131 if tail.len() > i * 4 {
132 self.h[i] ^= Self::mix(k[i], i);
133 }
134 }
135 let length = self.blocks.length as u32;
136 let h = &mut self.h;
137 for v in h.iter_mut() {
138 *v ^= length;
139 }
140 let sum = |h: &mut [u32; 4]| {
141 h[0] = h[0].wrapping_add(h[1]).wrapping_add(h[2]).wrapping_add(h[3]);
142 h[1] = h[1].wrapping_add(h[0]);
143 h[2] = h[2].wrapping_add(h[0]);
144 h[3] = h[3].wrapping_add(h[0]);
145 };
146 sum(h);
147 for v in h.iter_mut() {
148 *v = fmix32(*v);
149 }
150 sum(h);
151 h.iter().flat_map(|v| v.to_be_bytes()).collect()
152 }
155pub struct Murmur128x64 {
156 blocks: Blocks<16>,
157 h1: u64,
158 h2: u64,
161const X64_C1: u64 = 0x87c37b91114253d5;
162const X64_C2: u64 = 0x4cf5ad432745937f;
164impl Murmur128x64 {
165 pub fn new(seed: u64) -> Self {
166 Self { blocks: Blocks::new(), h1: seed, h2: seed }
167 }
168 pub fn update(&mut self, input: &[u8]) {
169 let (h1, h2) = (&mut self.h1, &mut self.h2);
170 self.blocks.feed(input, |b| {
171 let k1 = le64(b).wrapping_mul(X64_C1).rotate_left(31).wrapping_mul(X64_C2);
172 *h1 ^= k1;
173 *h1 = h1.rotate_left(27).wrapping_add(*h2).wrapping_mul(5).wrapping_add(0x52dce729);
174 let k2 = le64(&b[8..]).wrapping_mul(X64_C2).rotate_left(33).wrapping_mul(X64_C1);
175 *h2 ^= k2;
176 *h2 = h2.rotate_left(31).wrapping_add(*h1).wrapping_mul(5).wrapping_add(0x38495ab5);
177 });
178 }
179 pub fn finish(mut self) -> Vec<u8> {
180 let tail = self.blocks.tail().to_vec();
181 let (mut k1, mut k2) = (0u64, 0u64);
182 for (i, byte) in tail.iter().enumerate() {
183 if i >= 8 {
184 k2 ^= (*byte as u64) << ((i - 8) * 8);
185 } else {
186 k1 ^= (*byte as u64) << (i * 8);
187 }
188 }
189 if tail.len() > 8 {
190 self.h2 ^= k2.wrapping_mul(X64_C2).rotate_left(33).wrapping_mul(X64_C1);
191 }
192 if !tail.is_empty() {
193 self.h1 ^= k1.wrapping_mul(X64_C1).rotate_left(31).wrapping_mul(X64_C2);
194 }
195 let length = self.blocks.length;
196 self.h1 ^= length;
197 self.h2 ^= length;
198 self.h1 = self.h1.wrapping_add(self.h2);
199 self.h2 = self.h2.wrapping_add(self.h1);
200 self.h1 = fmix64(self.h1);
201 self.h2 = fmix64(self.h2);
202 self.h1 = self.h1.wrapping_add(self.h2);
203 self.h2 = self.h2.wrapping_add(self.h1);
204 [self.h1.to_be_bytes(), self.h2.to_be_bytes()].concat()
205 }
208pub struct SipHash24 {
209 blocks: Blocks<8>,
210 v: [u64; 4],
213impl SipHash24 {
214 pub fn new(key: &[u8]) -> Self {
215 let (k0, k1) = (le64(key), le64(&key[8..]));
216 Self { blocks: Blocks::new(), v: [0x736f6d6570736575 ^ k0, 0x646f72616e646f6d ^ k1, 0x6c7967656e657261 ^ k0, 0x7465646279746573 ^ k1] }
217 }
218 fn round(v: &mut [u64; 4]) {
219 v[0] = v[0].wrapping_add(v[1]);
220 v[1] = v[1].rotate_left(13) ^ v[0];
221 v[0] = v[0].rotate_left(32);
222 v[2] = v[2].wrapping_add(v[3]);
223 v[3] = v[3].rotate_left(16) ^ v[2];
224 v[0] = v[0].wrapping_add(v[3]);
225 v[3] = v[3].rotate_left(21) ^ v[0];
226 v[2] = v[2].wrapping_add(v[1]);
227 v[1] = v[1].rotate_left(17) ^ v[2];
228 v[2] = v[2].rotate_left(32);
229 }
230 fn compress(v: &mut [u64; 4], m: u64) {
231 v[3] ^= m;
232 Self::round(v);
233 Self::round(v);
234 v[0] ^= m;
235 }
236 pub fn update(&mut self, input: &[u8]) {
237 let v = &mut self.v;
238 self.blocks.feed(input, |b| Self::compress(v, le64(b)));
239 }
240 pub fn finish(mut self) -> Vec<u8> {
241 let mut last = (self.blocks.length & 0xff) << 56;
242 for (i, byte) in self.blocks.tail().iter().enumerate() {
243 last |= (*byte as u64) << (i * 8);
244 }
245 Self::compress(&mut self.v, last);
246 self.v[2] ^= 0xff;
247 for _ in 0..4 {
248 Self::round(&mut self.v);
249 }
250 (self.v[0] ^ self.v[1] ^ self.v[2] ^ self.v[3]).to_be_bytes().to_vec()
251 }
254pub struct Fnv {
255 bits: u32,
256 alternate: bool,
257 value: u64,
260impl Fnv {
261 pub fn new(bits: u32, alternate: bool) -> Self {
262 Self { bits, alternate, value: if bits == 32 { 0x811c9dc5 } else { 0xcbf29ce484222325 } }
263 }
264 pub fn update(&mut self, input: &[u8]) {
265 if self.bits == 32 {
266 let mut v = self.value as u32;
267 for b in input {
268 if self.alternate {
269 v = (v ^ *b as u32).wrapping_mul(0x01000193);
270 } else {
271 v = v.wrapping_mul(0x01000193) ^ *b as u32;
272 }
273 }
274 self.value = v as u64;
275 } else {
276 let mut v = self.value;
277 for b in input {
278 if self.alternate {
279 v = (v ^ *b as u64).wrapping_mul(0x100000001b3);
280 } else {
281 v = v.wrapping_mul(0x100000001b3) ^ *b as u64;
282 }
283 }
284 self.value = v;
285 }
286 }
287 pub fn finish(self) -> Vec<u8> {
288 if self.bits == 32 { (self.value as u32).to_be_bytes().to_vec() } else { self.value.to_be_bytes().to_vec() }
289 }
SHA-2562f17d77914114988fd1b792ae458fb7fa709061d066ade1b5557196e296d5460

CH-J Proprietary Software License 1.14 · Vir je na voljo pod CH-J Proprietary Software License 1.14. Njena razpoložljivost ne spreminja pogojev licence ali dodeljuje dodatnih pravic.

Arhiv SHA-256ac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f
Datoteke