//================================================================= // This file is a part of the Minimum Template Library. // By Limin Fu (phoolimin@gmail.com, lmfu@ucsd.edu) //================================================================= #include #include #include #include #include #include"minString.hxx" BEGIN_NS_MIN String::String( char ch ) { data = NULL; size = bufsize = 0; SetBytes( & ch, 1 ); } String::String( const char *s ) { data = NULL; size = bufsize = 0; *this = s; } String::String( const char *s, int n ) { data = NULL; size = bufsize = 0; SetBytes( s, n ); } String::String( const String & other ) { data = NULL; size = bufsize = 0; SetBytes( other.data, other.size ); } void String::Clear() { if( data ) free( data ); data = NULL; size = bufsize = 0; } void String::Reset() { if( size == 0 ) return; size = 0; data[0] = 0; } void String::Reserve( int n ) { if( bufsize >= n ) return; data = (char*) realloc( data, (n+1)*sizeof(char) ); bufsize = n; } void String::ResetSize( int n ) { if( size < n ) Resize( n, 0 ); size = n; data[size] = 0; } void String::Resize( int n, char ch ) { int i; if( bufsize != n ){ data = (char*) realloc( data, (n+1)*sizeof(char) ); bufsize = n; } for(i=size; i size ) return; Reserve( size + 1 ); if( at < size ) memmove( data + at + 1, data + at, (size - at) * sizeof(char) ); data[at] = ch; data[++size] = '\0'; } void String::Insert( char *chs, int at ) { if( chs == NULL ) return; if( at < 0 || at > size ) return; int i, N = strlen( chs ); Reserve( size + N ); if( at < size ) memmove( data + at + N, data + at, (size - at) * sizeof(char) ); for(i=0; i= size ) return; if( start + count > size ) count = size - start; rest = size - (start + count); if( rest ) memmove( data + start, data + start + count, rest * sizeof(char) ); size -= count; if( data ) data[size] = 0; } void String::Chop( int count ) { if( size ){ if( count > size ) count = size; Erase( size-count, count ); } } void String::ToUpper() { for(int i=0; i> 4 ]; shex += hex[ data[i] & 0xf ]; } return shex; } static void MD5_Append( String & md5, uint32_t h ) { const char *hex = "0123456789abcdef"; uint32_t k; k = (h >> 0) & 0xff; md5 += hex[k>>4]; md5 += hex[k&0xf]; k = (h >> 8) & 0xff; md5 += hex[k>>4]; md5 += hex[k&0xf]; k = (h >>16) & 0xff; md5 += hex[k>>4]; md5 += hex[k&0xf]; k = (h >>24) & 0xff; md5 += hex[k>>4]; md5 += hex[k&0xf]; } static void MD5_Update( uint32_t H[4], uint32_t W[16], uint32_t K[64] ) { static uint32_t R[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; uint32_t A = H[0]; uint32_t B = H[1]; uint32_t C = H[2]; uint32_t D = H[3]; uint32_t k; for(k=0; k<16; k++){ uint32_t f = (B & C) | ((~B) & D); uint32_t g = k; uint32_t t = D; uint32_t x = A + f + K[k] + W[g]; D = C; C = B; B = B + ((x << R[k]) | (x >> (32-R[k]))); A = t; } for(k=16; k<32; k++){ uint32_t f = (D & B) | ((~D) & C); uint32_t g = (k*5 + 1) % 16; uint32_t t = D; uint32_t x = A + f + K[k] + W[g]; D = C; C = B; B = B + ((x << R[k]) | (x >> (32-R[k]))); A = t; } for(k=32; k<48; k++){ uint32_t f = B ^ C ^ D; uint32_t g = (k*3 + 5) % 16; uint32_t t = D; uint32_t x = A + f + K[k] + W[g]; D = C; C = B; B = B + ((x << R[k]) | (x >> (32-R[k]))); A = t; } for(k=48; k<64; k++){ uint32_t f = C ^ (B | (~D)); uint32_t g = (k*7) % 16; uint32_t t = D; uint32_t x = A + f + K[k] + W[g]; D = C; C = B; B = B + ((x << R[k]) | (x >> (32-R[k]))); A = t; } H[0] += A; H[1] += B; H[2] += C; H[3] += D; } String String::MD5()const { String padding; uint64_t n, twop32 = ((uint64_t)1)<<32; uint32_t H[4] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476 }; uint32_t K[64], W[16]; int32_t i, k, m, chunks = size / 64; uint8_t *data = (uint8_t*) this->data; for(i=0; i<64; i++) K[i] = (uint32_t) floor( fabs( sin(i+1) ) * twop32 ); for(i=0; idata + chunks*64, m*sizeof(char) ); if( m + 8 > 64 ) padding.size = 128; chunks = padding.size / 64; data[m] = 1<<7; // first bit 1 followed by bit 0s; for(i=m+1; i> 8) & 0xff; data[i+2] = (n >> 16) & 0xff; data[i+3] = (n >> 24) & 0xff; data[i+4] = (n >> 32) & 0xff; data[i+5] = (n >> 40) & 0xff; data[i+6] = (n >> 48) & 0xff; data[i+7] = (n >> 56) & 0xff; for(i=0; i s.Size() ) length = s.Size(); return MurmurHash2( s.Data(), length, HASH_SEED ); } unsigned int MakeHash( const String & s, int offset, int length ) { if( offset < 0 ) offset = 0; if( length <= 0 ) length = s.Size() - offset; if( (length + offset) > s.Size() ) length = s.Size() - offset; return MurmurHash2( s.Data() + offset, length, HASH_SEED ); } int Compare( const String & left, const String & right ) { const char *L = left.Data(); const char *R = right.Data(); int M = left.Size(); int N = right.Size(); int I = 0; for(; I=0 ) M = lstart + 1 - max; if( rstart + 1 - max >=0 ) N = rstart + 1 - max; } for(; I>=M and J>=N and (mm+=(*L!=*R))<=maxmm; I--, J--, L--, R--); return lstart - I; } int CountMismatch( const String & left, const String & right, int from, int to ) { const char *L = left.Data() + from; const char *R = right.Data() + from; int M = left.Size(); int N = right.Size(); int i, mm = 0; if( to < 0 ) to = M; if( to > M ) to = M; if( to > N ) to = N; for(i=from; i M ) to = M; if( to > N ) to = N; for(i=from; i