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 if ((length - i) < 32) range = length - i;
00448 result += (getBitRange(i, range) * pow(2.0, i));
00449 }
00450
00451 return result;
00452 }
00453
00454
00455 OverlayKey OverlayKey::randomSuffix( uint32_t pos ) const
00456 {
00457 OverlayKey newKey = *this;
00458 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00459 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00460 mp_limb_t rnd;
00461
00462
00463 omnet_random(&rnd,1);
00464 newKey.key[i] &= ~m;
00465 newKey.key[i] |= (rnd&m);
00466
00467 omnet_random(newKey.key,i);
00468 newKey.trim();
00469
00470 return newKey;
00471 }
00472
00473
00474 OverlayKey OverlayKey::randomPrefix( uint32_t pos ) const
00475 {
00476 OverlayKey newKey = *this;
00477 int i = pos/GMP_LIMB_BITS, j = pos%GMP_LIMB_BITS;
00478 mp_limb_t m = ((mp_limb_t)1 << j)-1;
00479 mp_limb_t rnd;
00480
00481
00482 omnet_random(&rnd,1);
00483
00484 newKey.key[i] &= m;
00485 newKey.key[i] |= (rnd&~m);
00486 for (int k=aSize-1; k!=i; k--) {
00487
00488 omnet_random( &newKey.key[k], 1 );
00489 }
00490 newKey.trim();
00491
00492 return newKey;
00493 }
00494
00495
00496 uint32_t OverlayKey::sharedPrefixLength(const OverlayKey& compKey,
00497 uint32_t bitsPerDigit) const
00498 {
00499 if (compareTo(compKey) == 0) return keyLength;
00500
00501 uint32_t length = 0;
00502 int i;
00503 uint32_t j;
00504 bool msb = true;
00505
00506
00507 for (i=aSize-1; i>=0; --i) {
00508 if (this->key[i] != compKey.key[i]) {
00509
00510 mp_limb_t d = this->key[i] ^ compKey.key[i];
00511 if (msb) d <<= ( GMP_LIMB_BITS - (keyLength % GMP_LIMB_BITS) );
00512 for (j = GMP_LIMB_BITS-1; d >>= 1; --j);
00513 length += j;
00514 break;
00515 }
00516 length += GMP_LIMB_BITS;
00517 msb = false;
00518 }
00519
00520 return length / bitsPerDigit;
00521 }
00522
00523
00524 int OverlayKey::log_2() const
00525 {
00526 int16_t i = aSize-1;
00527
00528 while (i>=0 && key[i]==0) {
00529 i--;
00530 }
00531
00532 if (i<0) {
00533 return -1;
00534 }
00535
00536 mp_limb_t j = key[i];
00537 i *= GMP_LIMB_BITS;
00538 while (j!=0) {
00539 j >>= 1;
00540 i++;
00541 }
00542
00543 return i-1;
00544 }
00545
00546
00547 size_t OverlayKey::hash() const
00548 {
00549 return (size_t)key[0];
00550 }
00551
00552
00553 bool OverlayKey::isBetween(const OverlayKey& keyA,
00554 const OverlayKey& keyB) const
00555 {
00556 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00557 return false;
00558
00559 if (*this == keyA)
00560 return false;
00561 else if (keyA < keyB)
00562 return ((*this > keyA) && (*this < keyB));
00563 else
00564 return ((*this > keyA) || (*this < keyB));
00565 }
00566
00567
00568 bool OverlayKey::isBetweenR(const OverlayKey& keyA,
00569 const OverlayKey& keyB) const
00570 {
00571 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00572 return false;
00573
00574 if ((keyA == keyB) && (*this == keyA))
00575 return true;
00576 else if (keyA <= keyB)
00577 return ((*this > keyA) && (*this <= keyB));
00578 else
00579 return ((*this > keyA) || (*this <= keyB));
00580 }
00581
00582
00583 bool OverlayKey::isBetweenL(const OverlayKey& keyA,
00584 const OverlayKey& keyB) const
00585 {
00586 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00587 return false;
00588
00589 if ((keyA == keyB) && (*this == keyA))
00590 return true;
00591 else if (keyA <= keyB)
00592 return ((*this >= keyA) && (*this < keyB));
00593 else
00594 return ((*this >= keyA) || (*this < keyB));
00595 }
00596
00597
00598 bool OverlayKey::isBetweenLR(const OverlayKey& keyA,
00599 const OverlayKey& keyB) const
00600 {
00601 if (isUnspec || keyA.isUnspec || keyB.isUnspec)
00602 return false;
00603
00604 if ((keyA == keyB) && (*this == keyA))
00605 return true;
00606 else if (keyA <= keyB)
00607 return ((*this >= keyA) && (*this <= keyB));
00608 else
00609 return ((*this >= keyA) || (*this <= keyB));
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 std::ostream& operator<<(std::ostream& os, const OverlayKey& c)
00619 {
00620 os << c.toString(16);
00621 return os;
00622 };
00623
00624
00625 OverlayKey OverlayKey::getMax()
00626 {
00627 OverlayKey newKey;
00628
00629 for (uint32_t i=0; i<aSize; i++) {
00630 newKey.key[i] = ~0;
00631 }
00632 newKey.isUnspec = false;
00633 newKey.trim();
00634
00635 return newKey;
00636 }
00637
00638
00639 OverlayKey OverlayKey::random()
00640 {
00641 OverlayKey newKey = ZERO;
00642
00643 omnet_random(newKey.key,aSize);
00644
00645 newKey.trim();
00646
00647 return newKey;
00648 }
00649
00650
00651 OverlayKey OverlayKey::sha1(const BinaryValue& input)
00652 {
00653 OverlayKey newKey = OverlayKey();
00654 uint8_t temp[20];
00655 CSHA1 sha1;
00656
00657 sha1.Reset();
00658 sha1.Update((uint8_t*)(&(*input.begin())), input.size());
00659 sha1.Final();
00660 sha1.GetHash(temp);
00661 mpn_set_str(newKey.key, (const uint8_t*)temp,
00662 (int)std::min((uint32_t)(aSize * sizeof(mp_limb_t)), 20U), 256);
00663 newKey.isUnspec = false;
00664 newKey.trim();
00665
00666 return newKey;
00667 }
00668
00669
00670 OverlayKey OverlayKey::pow2( uint32_t exponent )
00671 {
00672 if (exponent >= keyLength) {
00673 throw cRuntimeError("OverlayKey::pow2(): "
00674 "exponent >= keyLength!");
00675 }
00676
00677 OverlayKey newKey = ZERO;
00678
00679 newKey.key[exponent/GMP_LIMB_BITS] =
00680 (mp_limb_t)1 << (exponent % GMP_LIMB_BITS);
00681
00682 return newKey;
00683 }
00684
00685
00686 void OverlayKey::test()
00687 {
00688
00689 cout << endl << "--- Add test ..." << endl;
00690 OverlayKey key = 123456789;
00691 cout << " key=" << key << endl;
00692 cout << " key += 987654321 = " << (key+=987654321) << endl;
00693 cout << " prefix++ : " << (++key) << endl;
00694 cout << " postfix++ : " << (key++) << endl;
00695 cout << " key=" << key << endl;
00696
00697 OverlayKey k1 = 256, k2 = 10, k3 = 3;
00698
00699
00700 cout << endl << "--- Compare test ..." << endl;
00701 cout << " 256 < 10 = "<< (k1 < k2) << " k1="<<k1<<endl;
00702 cout << " 256 > 10 = "<< (k1 > k2) << " k2="<<k2<<endl;
00703
00704 cout << " 10 isBetween(3, 256)=" << k2.isBetween(k3, k1) << endl;
00705 cout << " 3 isBetween(10, 256)=" << k3.isBetween(k2, k1) << endl;
00706 cout << " 256 isBetween(10, 256)=" << k1.isBetween(k2, k1) << endl;
00707 cout << " 256 isBetweenR(10, 256)=" << k1.isBetweenR(k2, k1) << endl;
00708 cout << " max isBetween(max-1,0)=" << OverlayKey::getMax().isBetween(
00709 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00710 cout << " max-1 isBetween(max,1)=" << (OverlayKey::getMax()-1).isBetween(
00711 OverlayKey::getMax(), OverlayKey::ONE) << endl;
00712 cout << " max-1 isBetweenL(max-1,1)=" << (OverlayKey::getMax()-1).
00713 isBetweenL(OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00714 cout << " 1 isBetweenL(max-1,1)=" << (OverlayKey::ONE).isBetweenL(
00715 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00716 cout << " 1 isBetweenR(max-1,1)=" << OverlayKey::ONE.isBetweenR(
00717 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00718 cout << " 1 isBetween(max-1,1)=" << OverlayKey::ONE.isBetween(
00719 OverlayKey::getMax()-1, OverlayKey::ONE) << endl;
00720 cout << " 1 isBetween(max-1,0)=" << OverlayKey::ONE.isBetween(
00721 OverlayKey::getMax()-1, OverlayKey::ZERO) << endl;
00722 cout << " 256 sharedPrefixLength(3)=" << k1.sharedPrefixLength(k3)
00723 << endl;
00724 cout << " 256 sharedPrefixLength(256)=" << k1.sharedPrefixLength(k1)
00725 << endl;
00726
00727
00728 cout << endl << "--- Warp around test ..." << endl;
00729
00730 k1 = OverlayKey::getMax();
00731 cout << "k1=max= " << k1.toString(16) << endl;
00732 cout << "k1+1 = " << (k1 + 1).toString(16) << endl;
00733 cout << "k1+2 = " << (k1 + 2).toString(16) << endl;
00734
00735 k1 = OverlayKey::ZERO;
00736 cout << "k1=0= " << k1.toString(16) << endl;
00737 cout << "k1-1 = " << (k1 - 1).toString(16) << endl;
00738 cout << "k1-2 = " << (k1 - 2).toString(16) << endl;
00739
00740 cout << "max > ONE=" << (OverlayKey::getMax() > OverlayKey::ONE) << endl;
00741 cout << "max < ONE=" << (OverlayKey::getMax() < OverlayKey::ONE) << endl;
00742
00743
00744 cout << endl << "--- Distance test ..." << endl;
00745
00746 cout << "KeyRingMetric::distance(1, max)="
00747 << KeyRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00748 cout << "KeyUniRingMetric::distance(1, max)="
00749 << KeyUniRingMetric().distance(OverlayKey::ONE, OverlayKey::getMax()) << endl;
00750 cout << "KeyRingMetric::distance(max, 1)="
00751 << KeyRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00752 cout << "KeyUniRingMetric::distance(max, 1)="
00753 << KeyUniRingMetric().distance(OverlayKey::getMax(), OverlayKey::ONE) << endl;
00754
00755
00756 cout << endl << "--- RandomSuffix and log2 test ..." << endl;
00757 k1 = OverlayKey::ZERO;
00758 for (uint32_t i=0; i<k1.getLength(); i++) {
00759 k2=k1.randomSuffix(i);
00760 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00761 }
00762 cout << endl << "--- RandomPrefix and log2 test ..." << endl;
00763 k1 = OverlayKey::getMax();
00764 for (uint32_t i=0; i<k1.getLength(); i++) {
00765 k2=k1.randomPrefix(i);
00766 cout << " " << k2.toString(16) << " log2=" << k2.log_2() << endl;
00767 }
00768
00769 cout << endl << "--- pow2 test..." << endl;
00770 for (uint32_t i=0; i<k1.getLength(); i++) {
00771 k2=pow2(i);
00772 cout << " 2^" << i << " = " << k2.toString(16) << " log2="
00773 << k2.log_2() << endl;
00774 }
00775
00776 cout << endl << "--- Bits test ..." << endl << " ";
00777 const char* BITS[] = { "000","001","010","011","100","101","110","111" };
00778 k1 = OverlayKey::random();
00779 for (int i=k1.getLength()-1; i>=0; i--)
00780 cout << k1[i];
00781 cout << " = " << endl << " ";
00782 for (int i=k1.getLength()-3; i>=0; i-=3)
00783 cout << BITS[k1.getBitRange(i,3)];
00784 cout << endl;
00785
00786 cout << endl << "--- SHA1 test ... (verified with test vectors)" << endl;
00787 cout << " Empty string: " << OverlayKey::sha1("").toString(16)
00788 << " = da39a3ee5e6b4b0d3255bfef95601890afd80709" << endl;
00789 cout << " 'Hello World' string: "
00790 << OverlayKey::sha1("Hello World").toString(16)
00791 << " = 0a4d55a8d778e5022fab701977c5d840bbc486d0" << endl;
00792 }
00793
00794
00795
00796
00797
00798
00799 inline void OverlayKey::trim()
00800 {
00801 key[aSize-1] &= GMP_MSB_MASK;
00802 }
00803
00804
00805
00806 int OverlayKey::compareTo( const OverlayKey& compKey ) const
00807 {
00808 if (compKey.isUnspec || isUnspec)
00809 opp_error("OverlayKey::compareTo(): key is unspecified!");
00810 return mpn_cmp(key,compKey.key,aSize);
00811 }
00812
00813
00814 inline void OverlayKey::clear()
00815 {
00816 memset( key, 0, aSize * sizeof(mp_limb_t) );
00817 isUnspec = false;
00818 }
00819
00820
00821 inline void omnet_random(mp_limb_t *r1p, mp_size_t r1n)
00822 {
00823
00824 uint32_t* chunkPtr = (uint32_t*)r1p;
00825
00826 for (uint32_t i=0; i < ((r1n*sizeof(mp_limb_t) + 3) / 4); i++) {
00827 chunkPtr[i] = intuniform(0, 0xFFFFFFFF);
00828 }
00829 }
00830
00831 #ifdef __GMP_SHORT_LIMB
00832 #define GMP_TYPE unsigned int
00833 #else
00834 #ifdef _LONG_LONG_LIMB
00835 #define GMP_TYPE unsigned long long int
00836 #else
00837 #define GMP_TYPE unsigned long int
00838 #endif
00839 #endif
00840
00841 void OverlayKey::netPack(cCommBuffer *b)
00842 {
00843
00844
00845
00846
00847 doPacking(b,(uint32_t*)this->key, MAX_KEYLENGTH / (8*sizeof(uint32_t)) +
00848 (MAX_KEYLENGTH % (8*sizeof(uint32_t))!=0 ? 1 : 0));
00849 doPacking(b,this->isUnspec);
00850 }
00851
00852 void OverlayKey::netUnpack(cCommBuffer *b)
00853 {
00854
00855
00856 doUnpacking(b,(uint32_t*)this->key, MAX_KEYLENGTH / (8*sizeof(uint32_t)) +
00857 (MAX_KEYLENGTH % (8*sizeof(uint32_t))!=0 ? 1 : 0));
00858 doUnpacking(b,this->isUnspec);
00859
00860 }
00861