BigNum BigNum::operator /(const BigNum& operand) const { std::vector<uint8_t> quotient, current; bool started = false; for (ssize_t i = data.size() - 1; i >= 0; i--) { current.push_back(data[i]); BigNum bcurrent(current); uint8_t q = bcurrent.smallDivide(operand); current = (bcurrent - ((operand) * BigNum(q))).toVector(); if (started or q != 0) { started = true; quotient.push_back(q); } } return BigNum(quotient, negative xor operand.negative); }
void DhHandshake::set_config(int32 g_int, Slice prime_str) { has_config_ = true; prime_ = BigNum::from_binary(prime_str); prime_str_ = prime_str.str(); b_ = BigNum(); g_b_ = BigNum(); BigNum::random(b_, 2048, -1, 0); // g^b g_int_ = g_int; g_.set_value(g_int_); BigNum::mod_exp(g_b_, g_, b_, prime_, ctx_); }
BigNum BigNum::operator +(const BigNum& operand) const { if (negative) return -((-*this) + -operand); if (operand.negative) { //compare BigNum abs(operand.abs()); if (operator==(abs)) return BigNum(0); if (operator<(abs)) return -(abs - *this); //do subtract here //we are sure here: *this > operand (strictly) vector<uint8_t> ret(data); int carry = 0; for (int i = 0; i < data.size(); i++) { if (i < operand.data.size()) //if digit exists in b carry += operand.data[i]; int tmp = (int) ret[i] - carry; if (tmp < 0) { carry = 1; ret[i] = tmp + (1 << 8); } else { ret[i] = tmp; carry = 0; } } //because *this > operand. carry must be 0 here //this refinement is redudant but just because of the sake of logic while (not ret.empty() and *ret.rbegin() == 0) ret.pop_back(); BigNum big(0); big.data = ret; return big; } //do plus here vector<uint8_t> ret(data); int carry = 0; for (int i = 0; i < data.size(); i++) { if (i < operand.data.size()) //if digit exists in b carry += operand.data[i]; int tmp = (int) ret[i] + carry; carry = tmp >> 8; ret[i] = tmp bitand ((1 << 8) - 1); } while (carry > 0) { ret.push_back(carry & ((1 << 8) - 1)); carry >>= 8; } while (not ret.empty() and *ret.rbegin() == 0) ret.pop_back(); BigNum r(0); r.data = ret; return r; }
int main() { int a[10]={1,2,3,4,5,6,7,8,9,10}; //创建链表 LinkInfo *L=CreateInfoFromArray(a,10); //1-单链表反转 ReverseList(L); ReverseList(L); //2-倒数第K个的验证 node* last[11]; for(int i=0;i<11;i++) last[i]=lastK(*L,i+1); //3-中间元素 node* mid=FinMid(*L); //4-删除无头结点 //DelNoHead(L->head->next); //5-有序链表合并 int a1[5]={5,5,4,3,1}; int b1[3]={7,4,2}; LinkInfo *p=CreateInfoFromArray(a1,0);//测试案例: 1-p,q 递增 2-p,q递减 3-p为空 4-q为空 5-p,q均为空 LinkInfo *q=CreateInfoFromArray(b1,3); MergeList(p,q); //6-判断链表是否有环(并返回环的起点node*) LinkInfo *circle=CreateInfoFromArray(a,6);//测试:有环、无环、空链表 node *nocross=IfCircle(circle->head); circle->tail->next=circle->head->next->next->next;//构造一个环 node *cross=IfCircle(circle->head); //7+8-两个单链表是否相交?求交点 LinkInfo *A=CreateInfoFromArray(a1,5);//测试:1-不交叉 2- 交叉 3- 空链表 LinkInfo *B=CreateInfoFromArray(b1,3); node *nointersection1=Intersection1(A->head,B->head); node *nointersection2=Intersection2(A->head,B->head);//NULL B->tail->next=A->head->next->next->next;//设置交叉点在4 node *intersection1=Intersection1(A->head,B->head); node *intersection2=Intersection1(A->head,B->head);// 4 //9-单链表排序 int s[10]={54,41,32,1,6,4,54,32,658,2}; LinkInfo *linksort=CreateInfoFromArray(s,10); LinkSortQ(linksort,0); //10-删除重复元素 DelRepeated(linksort); //11-拆分链表 LinkInfo *odd=CreateLinkInfo(); LinkInfo *even=CreateLinkInfo(); SplitList(L,odd,even); //12-大整数加法 char numa[]="-7987465413213546465461111111111"; char numb[]="-574968465216352468749611"; char* result=BigNum(numa,numb); return 0; }
//相除 void BigNum::div(BigNum& otherNum) { if (this->cmp(otherNum)<0) { *this = BigNum(0); } else if (this->cmp(otherNum) == 0) { *this = BigNum(1); } else { BigNum resultNum(1); this->sub(otherNum); while (this->cmp(otherNum) >= 0) { this->sub(otherNum); ++resultNum; } *this = resultNum; } }
uint8_t BigNum::smallDivide(BigNum const& devider) { int16_t low = 0; int16_t high = (1 << 8) - 1; while (low <= high) { uint8_t mid = (low + high) >> 1; if (operator<(devider * BigNum(mid))) //low = high + 1 //divider * high <= dividend < divider * (high + 1) high = (int16_t) mid - 1; else low = (int16_t) mid + 1; } return (uint8_t) high; }
BigNum BigNum::exponent(long long const& exp, BigNum const& modulus) const { if (exp == 0) return BigNum(1); BigNum result(this->exponent(exp >> 1, modulus)); //square result here result = result * result; if (modulus != 0) result = result % modulus; if (exp bitand 1) { //odd result = result * *this; if (modulus != 0) result = result % modulus; } return result; }
Vector2 Vector2::operator/(BigNum d) { return (*this) * Vector2(BigNum(1)/d, BigNum(1)/d); }
Vector2 Vector2::operator/(Vector2 v) { return (*this) * Vector2(BigNum(1)/v.x, BigNum(1)/v.y); }
BigNum BigNum::fromBase64(const std::vector<unsigned char> &b64) { return BigNum(Base64::decode(b64)); }