#![allow(unused)]
use gf2::*;
pub fn first_set<Word: Unsigned>(bv: &BitVector<Word>) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in 0..len {
if bv[i] {
return Some(i);
}
}
None
}
pub fn last_set<Word: Unsigned>(bv: &BitVector<Word>) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in (0..len).rev() {
if bv[i] {
return Some(i);
}
}
None
}
pub fn next_set<Word: Unsigned>(bv: &BitVector<Word>, index: usize) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in index + 1..len {
if bv[i] {
return Some(i);
}
}
None
}
pub fn previous_set<Word: Unsigned>(bv: &BitVector<Word>, index: usize) -> Option<usize> {
let len = bv.len();
if len == 0 || index == 0 {
return None;
}
for i in (0..index).rev() {
if bv[i] {
return Some(i);
}
}
None
}
pub fn first_unset<Word: Unsigned>(bv: &BitVector<Word>) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in 0..len {
if !bv[i] {
return Some(i);
}
}
None
}
pub fn last_unset<Word: Unsigned>(bv: &BitVector<Word>) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in (0..len).rev() {
if !bv[i] {
return Some(i);
}
}
None
}
pub fn previous_unset<Word: Unsigned>(bv: &BitVector<Word>, index: usize) -> Option<usize> {
let len = bv.len();
if len == 0 || index == 0 {
return None;
}
for i in (0..index).rev() {
if !bv[i] {
return Some(i);
}
}
None
}
pub fn next_unset<Word: Unsigned>(bv: &BitVector<Word>, index: usize) -> Option<usize> {
let len = bv.len();
if len == 0 {
return None;
}
for i in index + 1..len {
if !bv[i] {
return Some(i);
}
}
None
}
pub fn to_binary_string<Word: Unsigned>(bv: &BitVector<Word>) -> String {
let len = bv.len();
if len == 0 {
return String::new();
}
let mut result = String::with_capacity(len);
for i in 0..len {
if bv[i] {
result.push('1');
}
else {
result.push('0');
}
}
result
}
pub fn to_hex_string<Word: Unsigned>(bv: &BitVector<Word>) -> String {
let len = bv.len();
if len == 0 {
return String::new();
}
let digits = (len + 3) / 4;
let mut result = String::with_capacity(digits + 2);
let n_hex_digits = len / 4;
for i in 0..n_hex_digits {
let index = 4 * i;
let mut num = 0;
if bv[index] {
num += 8;
}
if bv[index + 1] {
num += 4;
}
if bv[index + 2] {
num += 2;
}
if bv[index + 3] {
num += 1;
}
let num_str = format!("{:X}", num);
result.push_str(&num_str);
}
let k = len % 4;
if k != 0 {
let mut num = 0;
for i in 0..k {
if bv[len - 1 - i] {
num |= 1 << i;
}
}
let num_str = format!("{:X}", num);
result.push_str(&num_str);
result.push_str(&format!(".{}", 1 << k));
}
result
}
pub fn shift_right<Word: Unsigned>(bv: &BitVector<Word>, shift: usize) -> BitVector<Word> {
let len = bv.len();
if len == 0 || shift == 0 {
return bv.clone();
}
let mut result = BitVector::zeros(len);
if shift >= len {
return result;
}
for i in 0..len - shift {
if bv[i] {
result.set(i + shift, true);
}
}
result
}
pub fn shift_left<Word: Unsigned>(bv: &BitVector<Word>, shift: usize) -> BitVector<Word> {
let len = bv.len();
if len == 0 || shift == 0 {
return bv.clone();
}
let mut result = BitVector::zeros(len);
if shift >= len {
return result;
}
for i in shift..len {
if bv[i] {
result.set(i - shift, true);
}
}
result
}
pub fn convolution<Word: Unsigned>(lhs: &BitVector<Word>, rhs: &BitVector<Word>) -> BitVector<Word> {
if lhs.is_empty() || rhs.is_empty() {
return BitVector::new();
}
let mut result = BitVector::zeros(lhs.len() + rhs.len() - 1);
if lhs.none() || rhs.none() {
return result;
}
for i in 0..lhs.len() {
if lhs[i] {
for j in 0..rhs.len() {
if rhs[j] {
result.flip(i + j);
}
}
}
}
result
}
pub fn reduce_x_to_power_n<Word: Unsigned>(poly: &BitPolynomial<Word>, n: usize) -> BitPolynomial<Word> {
let mut poly = poly.clone();
poly.make_monic();
if poly.is_zero() {
return BitPolynomial::zero();
}
if poly.is_one() {
return BitPolynomial::zero();
}
if n == 0 {
return BitPolynomial::one();
}
let d = poly.degree();
if d == 1 {
return BitPolynomial::constant(poly.coeff(0));
}
let p: BitVector<Word> = poly.coefficients().slice(0..d).into();
if n < d {
return BitPolynomial::x_to_the(n);
}
if n == d {
return BitPolynomial::from_coefficients(p);
}
let mut result = p.clone();
for _ in d..n {
let add_p = result[d - 1];
result >>= 1;
if add_p {
result ^= &p;
}
}
BitPolynomial::from_coefficients(result)
}