00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <omnetpp.h>
00025
00026 #include "OverlayKey.h"
00027 #include "Comparator.h"
00028
00029 #include <BinaryValue.h>
00030 #include "SHA1.h"
00031
00032 using namespace std;
00033
00034 uint32_t OverlayKey::keyLength = MAX_KEYLENGTH;
00035
00036
00037
00038
00039
00040
00041 uint32_t OverlayKey::aSize = OverlayKey::keyLength / (8*sizeof(mp_limb_t)) +
00042 (OverlayKey::keyLength % (8*sizeof(mp_limb_t))
00043 != 0 ? 1 : 0);
00044
00045 mp_limb_t OverlayKey::GMP_MSB_MASK = (OverlayKey::keyLength % GMP_LIMB_BITS)
00046 != 0 ? (((mp_limb_t)1 << (OverlayKey::keyLength % GMP_LIMB_BITS))-1)
00047 : (mp_limb_t) - 1;
00048
00049
00050
00051
00052
00053
00054 const OverlayKey OverlayKey::UNSPECIFIED_KEY;
00055 const OverlayKey OverlayKey::ZERO((uint32_t)0);
00056 const OverlayKey OverlayKey::ONE((uint32_t)1);
00057
00058
00059
00060 const char* HEX = "0123456789abcdef";
00061
00062
00063
00064
00065
00066
00067 OverlayKey::OverlayKey()
00068 {
00069 isUnspec = true;
00070 }
00071
00072
00073 OverlayKey::OverlayKey(uint32_t num)
00074 {
00075 clear();
00076 key[0] = num;
00077 trim();
00078 }
00079
00080
00081 OverlayKey::OverlayKey(const unsigned char* buf, uint32_t size)
00082 {
00083 int trimSize, offset;
00084 clear();
00085 trimSize = (int)min((uint32_t) (aSize * sizeof(mp_limb_t)), size);
00086 offset = aSize * sizeof(mp_limb_t) - trimSize;
00087 memcpy( ((char*)key) + offset, buf, trimSize);
00088 trim();
00089 }
00090
00091
00092 OverlayKey::OverlayKey(const std::string& str, uint32_t base)
00093 {
00094 if ((base < 2) || (base > 16)) {
00095 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00096 }
00097
00098 string s(str);
00099 clear();
00100
00101 for (uint32_t i=0; i<s.size(); i++) {
00102 if ((s[i] >= '0') && (s[i] <= '9')) {
00103 s[i] -= '0';
00104 } else if ((s[i] >= 'a') && (s[i] <= 'f')) {
00105 s[i] -= ('a' - 10);
00106 } else if ((s[i] >= 'A') & (s[i] <= 'F')) {
00107 s[i] -= ('A' - 10);
00108 } else {
00109 throw cRuntimeError("OverlayKey::OverlayKey(): "
00110 "Invalid character in string!");
00111 }
00112 }
00113
00114 mpn_set_str ((mp_limb_t*)this->key, (const unsigned char*)s.c_str(),
00115 str.size(), base);
00116 trim();
00117 }
00118
00119
00120 OverlayKey::OverlayKey(const OverlayKey& rhs)
00121 {
00122 (*this) = rhs;
00123 }
00124
00125
00126 OverlayKey::~OverlayKey()
00127 {}
00128
00129
00130
00131
00132
00133 void OverlayKey::setKeyLength(uint32_t length)
00134 {
00135 if ((length < 1) || (length > OverlayKey::keyLength)) {
00136 opp_error("OverlayKey::setKeyLength(): length must be <= %i "
00137 "and setKeyLength() must not be called twice "
00138 "with different length!", MAX_KEYLENGTH);
00139 }
00140
00141 keyLength = length;
00142
00143 aSize = keyLength / (8*sizeof(mp_limb_t)) +
00144 (keyLength % (8*sizeof(mp_limb_t))!=0 ? 1 : 0);
00145
00146 GMP_MSB_MASK = (keyLength % GMP_LIMB_BITS)
00147 != 0 ? (((mp_limb_t)1 << (keyLength % GMP_LIMB_BITS))-1)
00148 : (mp_limb_t)-1;
00149 }
00150
00151
00152
00153 uint32_t OverlayKey::getLength()
00154 {
00155 return OverlayKey::keyLength;
00156 }
00157
00158 bool OverlayKey::isUnspecified() const
00159 {
00160 return isUnspec;
00161 }
00162
00163 std::string OverlayKey::toString(uint32_t base) const
00164 {
00165 if ((base != 2) && (base != 16)) {
00166 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00167 }
00168
00169 if (isUnspec)
00170 return std::string("<unspec>");
00171 else {
00172 char temp[MAX_KEYLENGTH+1];
00173
00174 if (base==16) {
00175 int k=0;
00176 for (int i=(keyLength-1)/4; i>=0; i--, k++)
00177 temp[k] = HEX[this->getBitRange
00178 (4*i,4)];
00179
00180 temp[k] = 0;
00181 return std::string((const char*)temp);
00182 } else if (base==2) {
00183 int k=0;
00184 for (int i=keyLength-1; i>=0; i-=1, k++)
00185 temp[k] = HEX[this->getBit(i)];
00186 temp[k] = 0;
00187 return std::string((const char*)temp);
00188 } else {
00189 throw cRuntimeError("OverlayKey::OverlayKey(): Invalid base!");
00190 }
00191
00192
00193 #if 0
00194 mp_size_t last = mpn_get_str((unsigned char*)temp, base,
00195 (mp_limb_t*)this->key, aSize);
00196 for (int i=0; i<last; i++) {
00197 temp[i] = HEX[temp[i]];
00198 }
00199 temp[last] = 0;
00200 return std::string((const char*)temp);
00201 #endif
00202
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 OverlayKey& OverlayKey::operator=(const OverlayKey& rhs)
00212 {
00213 isUnspec = rhs.isUnspec;
00214 memcpy( key, rhs.key, aSize*sizeof(mp_limb_t) );
00215 return *this;
00216 }
00217
00218
00219 OverlayKey& OverlayKey::operator--()
00220 {
00221 return (*this -= ONE);
00222 }
00223
00224
00225 OverlayKey OverlayKey::operator--(int)
00226 {
00227 OverlayKey clone = *this;
00228 *this -= ONE;
00229 return clone;
00230 }
00231
00232
00233 OverlayKey& OverlayKey::operator++()
00234 {
00235 return (*this += ONE);
00236 }
00237
00238
00239 OverlayKey OverlayKey::operator++(int)
00240 {
00241 OverlayKey clone = *this;
00242 *this += ONE;
00243 return clone;
00244 }
00245
00246
00247 OverlayKey& OverlayKey::operator+=( const OverlayKey& rhs )
00248 {
00249 mpn_add_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00250 trim();
00251 isUnspec = false;
00252 return *this;
00253 }
00254
00255
00256 OverlayKey& OverlayKey::operator-=( const OverlayKey& rhs )
00257 {
00258 mpn_sub_n((mp_limb_t*)key, (mp_limb_t*)key, (mp_limb_t*)rhs.key, aSize);
00259 trim();
00260 isUnspec = false;
00261 return *this;
00262 }
00263
00264
00265 OverlayKey OverlayKey::operator+(const OverlayKey& rhs) const
00266 {
00267 OverlayKey result = *this;
00268 result += rhs;
00269 return result;
00270 }
00271
00272
00273 OverlayKey OverlayKey::operator-(const OverlayKey& rhs) const
00274 {
00275 OverlayKey result = *this;
00276 result -= rhs;
00277 return result;
00278 }
00279
00280
00281 bool OverlayKey::operator<(const OverlayKey& compKey) const
00282 {
00283 return compareTo(compKey) < 0;
00284 }
00285 bool OverlayKey::operator>(const OverlayKey& compKey) const
00286 {
00287 return compareTo(compKey) > 0;
00288 }
00289 bool OverlayKey::operator<=(const OverlayKey& compKey) const
00290 {
00291 return compareTo(compKey) <=0;
00292 }
00293 bool OverlayKey::operator>=(const OverlayKey& compKey) const
00294 {
00295 return compareTo(compKey) >=0;
00296 }
00297 bool OverlayKey::operator==(const OverlayKey& compKey) const
00298 {
00299 return compareTo(compKey) ==0;
00300 }
00301 bool OverlayKey::operator!=(const OverlayKey& compKey) const
00302 {
00303 return compareTo(compKey) !=0;
00304 }
00305
00306
00307 OverlayKey OverlayKey::operator^ (const OverlayKey& rhs) const
00308 {
00309 OverlayKey result = *this;
00310 for (uint32_t i=0; i<aSize; i++) {
00311 result.key[i] ^= rhs.key[i];
00312 }
00313
00314 return result;
00315 }
00316
00317
00318 OverlayKey OverlayKey::operator| (const OverlayKey& rhs) const
00319 {
00320 OverlayKey result = *this;
00321 for (uint32_t i=0; i<aSize; i++) {
00322 result.key[i] |= rhs.key[i];
00323 }
00324
00325 return result;
00326 }
00327
00328
00329 OverlayKey OverlayKey::operator& (const OverlayKey& rhs) const
00330 {
00331 OverlayKey result = *this;
00332 for (uint32_t i=0; i<aSize; i++) {
00333 result.key[i] &= rhs.key[i];
00334 }
00335
00336 return result;
00337 }
00338
00339
00340 OverlayKey OverlayKey::operator~ () const
00341 {
00342 OverlayKey result = *this;
00343 for (uint32_t i=0; i<aSize; i++) {
00344 result.key[i] = ~key[i];
00345 }
00346 result.trim();
00347
00348 return result;
00349 }
00350
00351
00352 OverlayKey OverlayKey::operator>>(uint32_t num) const
00353 {
00354 OverlayKey result = ZERO;
00355 int i = num/GMP_LIMB_BITS;
00356
00357 num %= GMP_LIMB_BITS;
00358
00359 if (i>=(int)aSize)
00360 return result;
00361
00362 for (int j=0; j<(int)aSize-i; j++) {
00363 result.key[j] = key[j+i];
00364 }
00365 mpn_rshift(result.key,result.key,aSize,num);
00366 result.isUnspec = false;
00367 result.trim();
00368
00369 return result;
00370 }
00371
00372
00373 OverlayKey OverlayKey::operator<<(uint32_t num) const
00374 {
00375 OverlayKey result = ZERO;
00376 int i = num/GMP_LIMB_BITS;
00377
00378 num %= GMP_LIMB_BITS;
00379
00380 if (i>=(int)aSize)
00381 return result;
00382
00383 for (int j=0; j<(int)aSize-i; j++) {
00384 result.key[j+i] = key[j];
00385 }
00386 mpn_lshift(result.key,result.key,aSize,num);
00387 result.isUnspec = false;
00388 result.trim();
00389
00390 return result;
00391 }
00392
00393
00394 OverlayKeyBit OverlayKey::operator[](uint32_t n)
00395 {
00396 return OverlayKeyBit(getBit(n), n, this);
00397 }
00398
00399 OverlayKey& OverlayKey::setBit(uint32_t pos, bool value)
00400 {
00401 if (pos >= keyLength) {
00402 throw cRuntimeError("OverlayKey::setBitAt(): "
00403 "pos >= keyLength!");
00404 }
00405
00406 mp_limb_t digit = 1;
00407 digit = digit << (pos % GMP_LIMB_BITS);
00408
00409 if (value) {
00410 key[pos / GMP_LIMB_BITS] |= digit;
00411 } else {
00412
00413 key[pos / GMP_LIMB_BITS] &= ~digit;
00414 }
00415
00416 return *this;
00417 };
00418
00419
00420
00421
00422
00423
00424 uint32_t OverlayKey::getBitRange(uint32_t p, uint32_t n) const
00425 {
00426 int i = p / GMP_LIMB_BITS,
00427 f = p % GMP_LIMB_BITS,
00428 f2 = f + n - GMP_LIMB_BITS;
00429
00430 if ((p + n > OverlayKey::keyLength) || (n > 32)) {
00431 throw cRuntimeError("OverlayKey::get: Invalid range");
00432 }
00433 if (GMP_LIMB_BITS < 32) {
00434 throw cRuntimeError("OverlayKey::get: GMP_LIMB_BITS too small!");
00435 }
00436
00437 return ((key[i] >> f) |
00438 (f2 > 0 ? (key[i+1] << (GMP_LIMB_BITS - f)) : 0)) &
00439 (((uint32_t)(~0)) >> (GMP_LIMB_BITS - n));
00440 }
00441
00442 double OverlayKey::toDouble() const
00443 {
00444 double result = 0;
00445 uint8_t range = 32, length = getLength();
00446 for (uint8_t i = 0; i < length; i += 32) {
00447
00448
00449
00450 if ((length - i) < 32) range = length - i;
00451 result += (getBitRange(i, range) * pow(2, i));
00452 }
00453
00454 return result;
00455 }
00456
00457
00458 OverlayKey OverlayKey::randomSuffix( uint32_t pos ) const
00459 {
00460 OverlayKey newKey = *this;
00461 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00462 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00463 mp_limb_t rnd;
00464
00465
00466 omnet_random(&rnd,1);
00467 newKey.key[i] &= ~m;
00468 newKey.key[i] |= (rnd&m);
00469
00470 omnet_random(newKey.key,i);
00471 newKey.trim();
00472
00473 return newKey;
00474 }
00475
00476
00477 OverlayKey OverlayKey::randomPrefix( uint32_t pos ) const
00478 {
00479 OverlayKey newKey = *this;
00480 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00481 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00482 mp_limb_t rnd;
00483
00484
00485 omnet_random(&rnd,1);
00486
00487 newKey.key[i] &= m;
00488 newKey.key[i] |= (rnd&~m);
00489 for (int k=aSize-1; k!=i; k--) {
00490
00491 omnet_random( &newKey.key[k], 1 );
00492 }
00493 newKey.trim();
00494
00495 return newKey;
00496 }
00497
00498
00499 uint32_t OverlayKey::sharedPrefixLength(const OverlayKey& compKey,
00500 uint32_t bitsPerDigit) const
00501 {
00502 if (compareTo(compKey) == 0) return keyLength;
00503
00504 uint32_t length = 0;
00505 int i;
00506 uint32_t j;
00507 bool msb = true;
00508
00509
00510 for (i=aSize-1; i>=0; --i) {
00511 if (this->key[i] != compKey.key[i]) {
00512
00513 mp_limb_t d = this->key[i] ^ compKey.key[i];
00514 if (msb) d <<= ( GMP_LIMB_BITS - (keyLength % GMP_LIMB_BITS) );
00515 for (j = GMP_LIMB_BITS-1; d >>= 1; --j);
00516 length += j;
00517 break;
00518 }
00519 length += GMP_LIMB_BITS;
00520 msb = false;
00521 }
00522
00523 return length / bitsPerDigit;
00524 }
00525
00526
00527 int OverlayKey::log_2() const
00528 {
00529 int16_t i = aSize-1;
00530
00531 while (i>=0 && key[i]==0) {
00532 i--;
00533 }
00534
00535 if (i<0) {
00536 return -1;
00537 }
00538
00539 mp_limb_t j = key[i];
00540 i *= GMP_LIMB_BITS;
00541 while (j!=0) {
00542 j >>= 1;
00543 i++;
00544 }
00545
00546 return i-1;
00547 }
00548
00549
00550 size_t OverlayKey::hash() const
00551 {
00552 return (size_t)key[0];
00553 }
00554
00555
00556 bool OverlayKey::isBetween(const OverlayKey& keyA,
00557 const OverlayKey& keyB) const
00558 {
00559 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00560 return false;
00561
00562 if (*this == keyA)
00563 return false;
00564 else if (keyA < keyB)
00565 return ((*this > keyA) && (*this < keyB));
00566 else
00567 return ((*this > keyA) || (*this < keyB));
00568 }
00569
00570
00571 bool OverlayKey::isBetweenR(const OverlayKey& keyA,
00572 const OverlayKey& keyB) const
00573 {
00574 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00575 return false;
00576
00577 if ((keyA == keyB) && (*this == keyA))
00578 return true;
00579 else if (keyA <= keyB)
00580 return ((*this > keyA) && (*this <= keyB));
00581 else
00582 return ((*this > keyA) || (*this <= keyB));
00583 }
00584
00585
00586 bool OverlayKey::isBetweenL(const OverlayKey& keyA,
00587 const OverlayKey& keyB) const
00588 {
00589 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00590 return false;
00591
00592 if ((keyA == keyB) && (*this == keyA))
00593 return true;
00594 else if (keyA <= keyB)
00595 return ((*this >= keyA) && (*this < keyB));
00596 else
00597 return ((*this >= keyA) || (*this < keyB));
00598 }
00599
00600
00601 bool OverlayKey::isBetweenLR(const OverlayKey& keyA,
00602 const OverlayKey& keyB) const
00603 {
00604 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00605 return false;
00606
00607 if ((keyA == keyB) && (*this == keyA))
00608 return true;
00609 else if (keyA <= keyB)
00610 return ((*this >= keyA) && (*this <= keyB));
00611 else
00612 return ((*this >= keyA) || (*this <= keyB));
00613 }
00614
00615
00616
00617
00618
00619
00620
00621 std::ostream& operator<<(std::ostream& os, const OverlayKey& c)
00622 {
00623 os << c.toString(16);
00624 return os;
00625 };
00626
00627
00628 OverlayKey OverlayKey::getMax()
00629 {
00630 OverlayKey newKey;
00631
00632 for (uint32_t i=0; i<aSize; i++) {
00633 newKey.key[i] = ~0;
00634 }
00635 newKey.isUnspec = false;
00636 newKey.trim();
00637
00638 return newKey;
00639 }
00640
00641
00642 OverlayKey OverlayKey::random()
00643 {
00644 OverlayKey newKey = ZERO;
00645
00646 omnet_random(newKey.key,aSize);
00647
00648 newKey.trim();
00649
00650 return newKey;
00651 }
00652
00653
00654 OverlayKey OverlayKey::sha1(const BinaryValue& input)
00655 {
00656 OverlayKey newKey = OverlayKey();
00657 uint8_t temp[20];
00658 CSHA1 sha1;
00659
00660 sha1.Reset();
00661 sha1.Update((uint8_t*)(&(*input.begin())), input.size());
00662 sha1.Final();
00663 sha1.GetHash(temp);
00664 mpn_set_str(newKey.key, (const uint8_t*)temp,
00665 (int)std::min((uint32_t)(aSize * sizeof(mp_limb_t)), 20U), 256);
00666 newKey.isUnspec = false;
00667 newKey.trim();
00668
00669 return newKey;
00670 }
00671
00672
00673 OverlayKey OverlayKey::pow2( uint32_t exponent )
00674 {
00675 if (exponent >= keyLength) {
00676 throw cRuntimeError("OverlayKey::pow2(): "
00677 "exponent >= keyLength!");
00678 }
00679
00680 OverlayKey newKey = ZERO;
00681
00682 newKey.key[exponent/GMP_LIMB_BITS] =
00683 (mp_limb_t)1 << (exponent % GMP_LIMB_BITS);
00684
00685 return newKey;
00686 }
00687
00688
00689 void OverlayKey::test()
00690 {
00691
00692 cout << endl << "--- Add test ..." << endl;
00693 OverlayKey key = 123456789;
00694 cout << " key=" << key << endl;
00695 cout << " key += 987654321 = " << (key+=987654321) << endl;
00696 cout << " prefix++ : " << (++key) << endl;
00697 cout << " postfix++ : " << (key++) << endl;
00698 cout << " key=" << key << endl;
00699
00700 OverlayKey k1 = 256, k2 = 10, k3 = 3;
00701
00702
00703 cout << endl << "--- Compare test ..." << endl;
00704 cout << " 256 < 10 = "<< (k1 < k2) << " k1="<<k1<<endl;
00705 cout << " 256 > 10 = "<< (k1 > k2) << " k2="<<k2<<endl;
00706
00707 cout << " 10 isBetween(3, 256)=" << k2.isBetween(k3, k1) << endl;
00708 cout << " 3 isBetween(10, 256)=" << k3.isBetween(k2, k1) << endl;
00709 cout << " 256 isBetween(10, 256)=" << k1.isBetween(k2, k1) << endl;
00710 cout << " 256 isBetweenR(10, 256)=" << k1.isBetweenR(k2, k1) << endl;
00711 cout << " max isBetween(max-1,0)=" << OverlayKey::getMax().isBetween(
00712 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00713 cout << " max-1 isBetween(max,1)=" << (OverlayKey::getMax()-1).isBetween(
00714 OverlayKey::getMax(), OverlayKey::ONE) << endl;
00715 cout << " max-1 isBetweenL(max-1,1)=" << (OverlayKey::getMax()-1).
00716 isBetweenL(OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00717 cout << " 1 isBetweenL(max-1,1)=" << (OverlayKey::ONE).isBetweenL(
00718 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00719 cout << " 1 isBetweenR(max-1,1)=" << OverlayKey::ONE.isBetweenR(
00720 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00721 cout << " 1 isBetween(max-1,1)=" << OverlayKey::ONE.isBetween(
00722 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00723 cout << " 1 isBetween(max-1,0)=" << OverlayKey::ONE.isBetween(
00724 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00725 cout << " 256 sharedPrefixLength(3)=" << k1.sharedPrefixLength(k3)
00726 << endl;
00727 cout << " 256 sharedPrefixLength(256)=" << k1.sharedPrefixLength(k1)
00728 << endl;
00729
00730
00731 cout << endl << "--- Warp around test ..." << endl;
00732
00733 k1 = OverlayKey::getMax();
00734 cout << "k1=max= " << k1.toString(16) << endl;
00735 cout << "k1+1 = " << (k1 + 1).toString(16) << endl;
00736 cout << "k1+2 = " << (k1 + 2).toString(16) << endl;
00737
00738 k1 = OverlayKey::ZERO;
00739 cout << "k1=0= " << k1.toString(16) << endl;
00740 cout << "k1-1 = " << (k1 - 1).toString(16) << endl;
00741 cout << "k1-2 = " << (k1 - 2).toString(16) << endl;
00742
00743 cout << "max > ONE=" << (OverlayKey::getMax() > OverlayKey::ONE) << endl;
00744 cout << "max < ONE=" << (OverlayKey::getMax() < OverlayKey::ONE) << endl;
00745
00746
00747 cout << endl << "--- Distance test ..." << endl;
00748
00749 cout << "KeyRingMetric::distance(1, max)="
00750 << KeyRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00751 cout << "KeyUniRingMetric::distance(1, max)="
00752 << KeyUniRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00753 cout << "KeyRingMetric::distance(max, 1)="
00754 << KeyRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00755 cout << "KeyUniRingMetric::distance(max, 1)="
00756 << KeyUniRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00757
00758
00759 cout << endl << "--- RandomSuffix and log2 test ..." << endl;
00760 k1 = OverlayKey::ZERO;
00761 for (uint32_t i=0; i<k1.getLength(); i++) {
00762 k2=k1.randomSuffix(i);
00763 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00764 }
00765 cout << endl << "--- RandomPrefix and log2 test ..." << endl;
00766 k1 = OverlayKey::getMax();
00767 for (uint32_t i=0; i<k1.getLength(); i++) {
00768 k2=k1.randomPrefix(i);
00769 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00770 }
00771
00772 cout << endl << "--- pow2 test..." << endl;
00773 for (uint32_t i=0; i<k1.getLength(); i++) {
00774 k2=pow2(i);
00775 cout << " 2^" << i << " = " << k2.toString(16) << " log2="
00776 << k2.log_2() << endl;
00777 }
00778
00779 cout << endl << "--- Bits test ..." << endl << " ";
00780 const char* BITS[] = { "000","001","010","011","100","101","110","111" };
00781 k1 = OverlayKey::random();
00782 for (int i=k1.getLength()-1; i>=0; i--)
00783 cout << k1[i];
00784 cout << " = " << endl << " ";
00785 for (int i=k1.getLength()-3; i>=0; i-=3)
00786 cout << BITS[k1.getBitRange(i,3)];
00787 cout << endl;
00788
00789 cout << endl << "--- SHA1 test ... (verified with test vectors)" << endl;
00790 cout << " Empty string: " << OverlayKey::sha1("").toString(16)
00791 << " = da39a3ee5e6b4b0d3255bfef95601890afd80709" << endl;
00792 cout << " 'Hello World' string: "
00793 << OverlayKey::sha1("Hello World").toString(16)
00794 << " = 0a4d55a8d778e5022fab701977c5d840bbc486d0" << endl;
00795 }
00796
00797
00798
00799
00800
00801
00802 inline void OverlayKey::trim()
00803 {
00804 key[aSize-1] &= GMP_MSB_MASK;
00805 }
00806
00807
00808
00809 int OverlayKey::compareTo( const OverlayKey& compKey ) const
00810 {
00811 if (compKey.isUnspec || isUnspec)
00812 opp_error("OverlayKey::compareTo(): key is unspecified!");
00813 return mpn_cmp(key,compKey.key,aSize);
00814 }
00815
00816
00817 inline void OverlayKey::clear()
00818 {
00819 memset( key, 0, aSize * sizeof(mp_limb_t) );
00820 isUnspec = false;
00821 }
00822
00823
00824 inline void omnet_random(mp_limb_t *r1p, mp_size_t r1n)
00825 {
00826
00827 uint32_t* chunkPtr = (uint32_t*)r1p;
00828
00829 for (uint32_t i=0; i < ((r1n*sizeof(mp_limb_t) + 3) / 4); i++) {
00830 chunkPtr[i] = intuniform(0, 0xFFFFFFFF);
00831 }
00832 }
00833
00834 #ifdef __GMP_SHORT_LIMB
00835 #define GMP_TYPE unsigned int
00836 #else
00837 #ifdef _LONG_LONG_LIMB
00838 #define GMP_TYPE unsigned long long int
00839 #else
00840 #define GMP_TYPE unsigned long int
00841 #endif
00842 #endif
00843
00844 void OverlayKey::netPack(cCommBuffer *b)
00845 {
00846 doPacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00847 (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00848 doPacking(b,this->isUnspec);
00849 }
00850
00851 void OverlayKey::netUnpack(cCommBuffer *b)
00852 {
00853 doUnpacking(b,(GMP_TYPE*)this->key, MAX_KEYLENGTH / (8*sizeof(mp_limb_t)) +
00854 (MAX_KEYLENGTH % (8*sizeof(mp_limb_t))!=0 ? 1 : 0));
00855 doUnpacking(b,this->isUnspec);
00856
00857 }
00858