-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: normalize some files to LF endings
- Loading branch information
Showing
6 changed files
with
3,337 additions
and
3,337 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,34 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [0.2.1] - 2023-05-04 | ||
|
||
### Fixed | ||
|
||
- Fix overflow panic in debug builds when total length of data exceeds 1408534 bytes | ||
(~1.34MB). See [fcdf710](https://github.com/vthib/tlsh/commit/fcdf710ac5730e68f4e4bf987623bc0e9b8e0819). | ||
|
||
## [0.2.0] - 2023-01-01 | ||
|
||
### Added | ||
|
||
- Added TLSH difference computation (with the `diff` feature). | ||
- The crate is now `no_std`. | ||
- Tests now use reference files from the original TLSH repo to check conformance. | ||
- `TlshCore` renamed to `TlshBuilder`, new `Tlsh` object to compute hashes and differences. | ||
|
||
### Fixed | ||
|
||
- Fixed tests when run on Windows. | ||
|
||
### Removed | ||
|
||
- Remove `showvers` parameter in hash function. Hashes now always return the `T1` prefix. | ||
|
||
## [0.1.0] - 2022-12-30 | ||
|
||
Initial release | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [0.2.1] - 2023-05-04 | ||
|
||
### Fixed | ||
|
||
- Fix overflow panic in debug builds when total length of data exceeds 1408534 bytes | ||
(~1.34MB). See [fcdf710](https://github.com/vthib/tlsh/commit/fcdf710ac5730e68f4e4bf987623bc0e9b8e0819). | ||
|
||
## [0.2.0] - 2023-01-01 | ||
|
||
### Added | ||
|
||
- Added TLSH difference computation (with the `diff` feature). | ||
- The crate is now `no_std`. | ||
- Tests now use reference files from the original TLSH repo to check conformance. | ||
- `TlshCore` renamed to `TlshBuilder`, new `Tlsh` object to compute hashes and differences. | ||
|
||
### Fixed | ||
|
||
- Fixed tests when run on Windows. | ||
|
||
### Removed | ||
|
||
- Remove `showvers` parameter in hash function. Hashes now always return the `T1` prefix. | ||
|
||
## [0.1.0] - 2022-12-30 | ||
|
||
Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,132 +1,132 @@ | ||
use core::cmp::Ordering; | ||
|
||
use crate::BUCKETS; | ||
|
||
pub fn get_quartiles<const EFF_BUCKETS: usize>(bucket: &[u32; BUCKETS]) -> (u32, u32, u32) { | ||
let mut short_cut_left = [0; EFF_BUCKETS]; | ||
let mut short_cut_right = [0; EFF_BUCKETS]; | ||
let p1 = EFF_BUCKETS / 4 - 1; | ||
let p2 = EFF_BUCKETS / 2 - 1; | ||
let p3 = EFF_BUCKETS - EFF_BUCKETS / 4 - 1; | ||
let end = EFF_BUCKETS - 1; | ||
let mut q1 = 0; | ||
let q2; | ||
let mut q3 = 0; | ||
|
||
// Safety: this expect is eliminated at compile time, as the compiler can | ||
// trivially verify that EFF_BUCKETS <= BUCKETS. | ||
let mut bucket_copy: [u32; EFF_BUCKETS] = bucket[..EFF_BUCKETS] | ||
.try_into() | ||
.expect("EFF_BUCKETS is bigger than BUCKETS"); | ||
|
||
let mut spl = 0; | ||
let mut spr = 0; | ||
let mut l = 0; | ||
let mut r = end; | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p2) { | ||
Ordering::Greater => { | ||
r = ret - 1; | ||
short_cut_right[spr] = ret; | ||
spr += 1; | ||
} | ||
Ordering::Less => { | ||
l = ret + 1; | ||
short_cut_left[spl] = ret; | ||
spl += 1; | ||
} | ||
Ordering::Equal => { | ||
q2 = bucket_copy[p2]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
short_cut_left[spl] = p2 - 1; | ||
short_cut_right[spr] = p2 + 1; | ||
|
||
let mut l = 0; | ||
for mut r in short_cut_left.iter().take(spl + 1).copied() { | ||
match r.cmp(&p1) { | ||
Ordering::Greater => { | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p1) { | ||
Ordering::Greater => r = ret - 1, | ||
Ordering::Less => l = ret + 1, | ||
Ordering::Equal => { | ||
q1 = bucket_copy[p1]; | ||
break; | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
Ordering::Less => { | ||
l = r; | ||
} | ||
Ordering::Equal => { | ||
q1 = bucket_copy[p1]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
let mut r = end; | ||
for mut l in short_cut_right.iter().take(spr + 1).copied() { | ||
match l.cmp(&p3) { | ||
Ordering::Less => { | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p3) { | ||
Ordering::Greater => r = ret - 1, | ||
Ordering::Less => l = ret + 1, | ||
Ordering::Equal => { | ||
q3 = bucket_copy[p3]; | ||
break; | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
Ordering::Greater => { | ||
r = l; | ||
} | ||
Ordering::Equal => { | ||
q3 = bucket_copy[p3]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
(q1, q2, q3) | ||
} | ||
|
||
fn partition(buf: &mut [u32], left: usize, right: usize) -> usize { | ||
if left == right { | ||
return left; | ||
} | ||
if left + 1 == right { | ||
if buf[left] > buf[right] { | ||
buf.swap(left, right); | ||
} | ||
return left; | ||
} | ||
|
||
let mut ret = left; | ||
let pivot = (left + right) >> 1; | ||
let val = buf[pivot]; | ||
buf.swap(pivot, right); | ||
|
||
for i in left..right { | ||
if buf[i] < val { | ||
buf.swap(ret, i); | ||
ret += 1; | ||
} | ||
} | ||
buf[right] = buf[ret]; | ||
buf[ret] = val; | ||
|
||
ret | ||
} | ||
use core::cmp::Ordering; | ||
|
||
use crate::BUCKETS; | ||
|
||
pub fn get_quartiles<const EFF_BUCKETS: usize>(bucket: &[u32; BUCKETS]) -> (u32, u32, u32) { | ||
let mut short_cut_left = [0; EFF_BUCKETS]; | ||
let mut short_cut_right = [0; EFF_BUCKETS]; | ||
let p1 = EFF_BUCKETS / 4 - 1; | ||
let p2 = EFF_BUCKETS / 2 - 1; | ||
let p3 = EFF_BUCKETS - EFF_BUCKETS / 4 - 1; | ||
let end = EFF_BUCKETS - 1; | ||
let mut q1 = 0; | ||
let q2; | ||
let mut q3 = 0; | ||
|
||
// Safety: this expect is eliminated at compile time, as the compiler can | ||
// trivially verify that EFF_BUCKETS <= BUCKETS. | ||
let mut bucket_copy: [u32; EFF_BUCKETS] = bucket[..EFF_BUCKETS] | ||
.try_into() | ||
.expect("EFF_BUCKETS is bigger than BUCKETS"); | ||
|
||
let mut spl = 0; | ||
let mut spr = 0; | ||
let mut l = 0; | ||
let mut r = end; | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p2) { | ||
Ordering::Greater => { | ||
r = ret - 1; | ||
short_cut_right[spr] = ret; | ||
spr += 1; | ||
} | ||
Ordering::Less => { | ||
l = ret + 1; | ||
short_cut_left[spl] = ret; | ||
spl += 1; | ||
} | ||
Ordering::Equal => { | ||
q2 = bucket_copy[p2]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
short_cut_left[spl] = p2 - 1; | ||
short_cut_right[spr] = p2 + 1; | ||
|
||
let mut l = 0; | ||
for mut r in short_cut_left.iter().take(spl + 1).copied() { | ||
match r.cmp(&p1) { | ||
Ordering::Greater => { | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p1) { | ||
Ordering::Greater => r = ret - 1, | ||
Ordering::Less => l = ret + 1, | ||
Ordering::Equal => { | ||
q1 = bucket_copy[p1]; | ||
break; | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
Ordering::Less => { | ||
l = r; | ||
} | ||
Ordering::Equal => { | ||
q1 = bucket_copy[p1]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
let mut r = end; | ||
for mut l in short_cut_right.iter().take(spr + 1).copied() { | ||
match l.cmp(&p3) { | ||
Ordering::Less => { | ||
loop { | ||
let ret = partition(&mut bucket_copy, l, r); | ||
match ret.cmp(&p3) { | ||
Ordering::Greater => r = ret - 1, | ||
Ordering::Less => l = ret + 1, | ||
Ordering::Equal => { | ||
q3 = bucket_copy[p3]; | ||
break; | ||
} | ||
} | ||
} | ||
break; | ||
} | ||
Ordering::Greater => { | ||
r = l; | ||
} | ||
Ordering::Equal => { | ||
q3 = bucket_copy[p3]; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
(q1, q2, q3) | ||
} | ||
|
||
fn partition(buf: &mut [u32], left: usize, right: usize) -> usize { | ||
if left == right { | ||
return left; | ||
} | ||
if left + 1 == right { | ||
if buf[left] > buf[right] { | ||
buf.swap(left, right); | ||
} | ||
return left; | ||
} | ||
|
||
let mut ret = left; | ||
let pivot = (left + right) >> 1; | ||
let val = buf[pivot]; | ||
buf.swap(pivot, right); | ||
|
||
for i in left..right { | ||
if buf[i] < val { | ||
buf.swap(ret, i); | ||
ret += 1; | ||
} | ||
} | ||
buf[right] = buf[ret]; | ||
buf[ret] = val; | ||
|
||
ret | ||
} |
Oops, something went wrong.