void test_hash_multimap(){ const char * testfile = boost::archive::tmpnam(NULL); BOOST_REQUIRE(NULL != testfile); BOOST_CHECKPOINT("hash_multimap"); BOOST_STD_EXTENSION_NAMESPACE::hash_multimap<random_key, A> ahash_multimap; ahash_multimap.insert(std::make_pair(random_key(), A())); ahash_multimap.insert(std::make_pair(random_key(), A())); { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS); oa << boost::serialization::make_nvp("ahash_multimap", ahash_multimap); } BOOST_STD_EXTENSION_NAMESPACE::hash_multimap<random_key, A> ahash_multimap1; { test_istream is(testfile, TEST_STREAM_FLAGS); test_iarchive ia(is, TEST_ARCHIVE_FLAGS); ia >> boost::serialization::make_nvp("ahash_multimap", ahash_multimap1); } std::vector< std::pair<random_key, A> > tvec, tvec1; tvec.clear(); tvec1.clear(); std::copy(ahash_multimap.begin(), ahash_multimap.end(), std::back_inserter(tvec)); std::sort(tvec.begin(), tvec.end()); std::copy(ahash_multimap1.begin(), ahash_multimap1.end(), std::back_inserter(tvec1)); std::sort(tvec1.begin(), tvec1.end()); BOOST_CHECK(tvec == tvec1); std::remove(testfile); }
/** * Generate new token for given version string. */ static char * tok_generate(time_t now, const char *version) { char token[TOKEN_BASE64_SIZE + 1]; char digest[TOKEN_VERSION_SIZE]; char lvldigest[LEVEL_SIZE]; char lvlbase64[LEVEL_BASE64_SIZE + 1]; const struct tokkey *tk; uint32 crc32; uint idx; const char *key; SHA1Context ctx; struct sha1 sha1; int lvlsize; int i; /* * Compute token. */ key = random_key(now, &idx, &tk); now = clock_loc2gmt(now); /* As close to GMT as possible */ poke_be32(&digest[0], now); random_bytes(&digest[4], 3); digest[6] &= 0xe0U; /* Upper 3 bits only */ digest[6] |= idx & 0xffU; /* Has 5 bits for the index */ SHA1Reset(&ctx); SHA1Input(&ctx, key, strlen(key)); SHA1Input(&ctx, digest, 7); SHA1Input(&ctx, version, strlen(version)); SHA1Result(&ctx, &sha1); memcpy(&digest[7], sha1.data, SHA1_RAW_SIZE); /* * Compute level. */ lvlsize = G_N_ELEMENTS(token_keys) - (tk - token_keys); crc32 = crc32_update(0, digest, TOKEN_VERSION_SIZE); for (i = 0; i < lvlsize; i++) { poke_be16(&lvldigest[i*2], tok_crc(crc32, tk)); tk++; } /* * Encode into base64. */ base64_encode_into(digest, TOKEN_VERSION_SIZE, token, TOKEN_BASE64_SIZE); token[TOKEN_BASE64_SIZE] = '\0'; ZERO(&lvlbase64); base64_encode_into(lvldigest, 2 * lvlsize, lvlbase64, LEVEL_BASE64_SIZE); return g_strconcat(token, "; ", lvlbase64, (void *) 0); }
/* We don't want to spend a byte encoding sign, so make sure it's 0x2 */ static void gen_keys(secp256k1_context *ctx, struct seckey *seckey, struct compressed_pubkey *pubkey) { secp256k1_pubkey pkey; size_t len; random_key(ctx, seckey, &pkey); secp256k1_ec_pubkey_serialize(ctx, pubkey->u8, &len, &pkey, SECP256K1_EC_COMPRESSED); assert(len == sizeof(pubkey->u8)); }
void test_multimap(){ const char * testfile = boost::archive::tmpnam(NULL); BOOST_REQUIRE(NULL != testfile); BOOST_MESSAGE("multimap"); std::multimap<random_key, A> amultimap; amultimap.insert(std::make_pair(random_key(), A())); amultimap.insert(std::make_pair(random_key(), A())); { test_ostream os(testfile, TEST_STREAM_FLAGS); test_oarchive oa(os, TEST_ARCHIVE_FLAGS); oa << boost::serialization::make_nvp("amultimap", amultimap); } std::multimap<random_key, A> amultimap1; { test_istream is(testfile, TEST_STREAM_FLAGS); test_iarchive ia(is, TEST_ARCHIVE_FLAGS); ia >> boost::serialization::make_nvp("amultimap", amultimap1); } BOOST_CHECK(amultimap == amultimap1); std::remove(testfile); }
int cli_main(int argc, char* argv[]) { nistp224key sec; nistp224key pub; obuf out; str str = {0,0,0}; const char* home; const char* keypath; uskey_path = "secret"; upkey_path = "public"; if (argc > 0) keypath = argv[0]; else { if ((home = getenv("HOME")) == 0) die1(1, "$HOME is not set."); if (chdir(home) != 0) die3sys(1, "Could not change directory to '", home, "'"); mkdir(".srcmd", 0700); keypath = ".srcmd/key"; } mkdir(keypath, 0755); if (chdir(keypath) != 0) die3sys(1, "Could not chdir to '", keypath, "'"); random_key(sec); nistp224wrap(pub, BASEP224, sec); base64_encode_line(sec, sizeof sec, &str); if (!obuf_open(&out, uskey_path, OBUF_CREATE|OBUF_EXCLUSIVE, 0400, 0) || !obuf_putstr(&out, &str) || !obuf_putc(&out, '\n') || !obuf_close(&out)) die3sys(1, "Could not create secret key file '", uskey_path, "'"); str_truncate(&str, 0); base64_encode_line(pub, sizeof pub, &str); if (!obuf_open(&out, upkey_path, OBUF_CREATE|OBUF_EXCLUSIVE, 0444, 0) || !obuf_putstr(&out, &str) || !obuf_putc(&out, '\n') || !obuf_close(&out)) die3sys(1, "Could not create public key file '", upkey_path, "'"); msg3("Your public key is '", str.s, "'"); return 0; argc = 1; }
/* We don't want to spend a byte encoding sign, so make sure it's 0x2 */ static void gen_keys(secp256k1_context *ctx, struct seckey *seckey, struct onion_pubkey *pubkey) { unsigned char tmp[33]; secp256k1_pubkey pkey; size_t len = sizeof(tmp); random_key(ctx, seckey, &pkey); secp256k1_ec_pubkey_serialize(ctx, tmp, &len, &pkey, SECP256K1_EC_COMPRESSED); assert(len == sizeof(tmp)); if (tmp[0] == 0x3) flip_key(seckey); memcpy(pubkey, tmp+1, sizeof(*pubkey)); }
int main() { long long duration, t1, t2; struct timeval tv; int i, key_size, value_buffer_size; kvs_env.init_type = INIT_TYPE_LOAD; kvs_env.disk_file_path = "disk_file"; kvs_env.IMAGE_file_path = "IMAGE_file"; kvs_env.log_file_path = "log_file"; kvs_env.buffer_sleep_time = 0; kvs_env.buffer_horizon_size = 100 * 1024 * 1024; kvs_env.buffer_size = 700 * 1024 * 1024; srand((unsigned) time(NULL)); if (kv_init(&kvs_env) != 0) { printf("kvs_init fail\n"); return -1; } duration = 0; for (i = 0; i < 50000; i++) { random_key(key_buffer, CNT - 1, &key_size); gettimeofday(&tv, NULL); t1 = tv.tv_sec * 1000 * 1000 + tv.tv_usec; if (kv_get(key_buffer, key_size, value_buffer, &value_buffer_size) != 0) { printf("kv_get fail\n"); return -1; } gettimeofday(&tv, NULL); t2 = tv.tv_sec * 1000 * 1000 + tv.tv_usec; duration += (t2 - t1) / 1000; } kv_exit(); printf("total read time: %lld ms\n", duration); return 0; }
int main() { std::cerr << "dictionary_benchmark compiled " << __DATE__ << " " << __TIME__ << std::endl; //std::srand(std::time(0)); std::srand(4242); // we need repeatable results #ifndef NDEBUG std::ofstream output("results_debug.csv"); #else std::ofstream output("results_release.csv"); #endif output << "elements,small cctor,large cctor,small find,large find," << "hash_map small cctor,hash_map large cctor,hash_map small find,hash_map large find," << "std::map small cctor,std::map large cctor,std::map small find,std::map large find" << std::endl; #if 0 for (int i(0); i < 20; ++i) std::cout << random_key().c_str() << std::endl; #else const std::size_t maximumSize = 2500; const std::size_t sizeIncrement = 25; const std::size_t repeatMaximum = 500000000L / maximumSize; for (std::size_t i(0); i <= maximumSize; i += sizeIncrement) { // try to keep the execution time close to constant per size // this is entirely for the sanity and patience of the // person running and debugging this code :-) std::size_t iterations = repeatMaximum / (i+1); if (iterations < 2) iterations = 2; do_test(i, output, iterations); } #endif }
int main(int argc, char ** argv) { int i; // do we have verbose output? bool ga_testing = false; if (argc > 1) { for (i = 1; i < argc; ++i) { if (!strcmp(argv[1],"-ga")) { ga_testing = true; break; } } } // initialize btree * tree = create_btree(16); bool flags[MAX_KEY]; for (i = 0; i < MAX_KEY; ++i) flags[i] = false; // get starting time struct timespec start, stop; clock_gettime(CLOCK_REALTIME,&start); // what we're timing for (int n = 0; n < TEST_SIZE; ++n) { // pick a key btree_key_t key = random_key(MAX_KEY); // is the key in the tree? btree_data_t data = btree_find(tree,key); if (data == NULL_DATA) { btree_insert(tree,key,(btree_data_t)key); flags[key] = true; } else { btree_remove(tree,key); flags[key] = false; } } // calculate run time clock_gettime(CLOCK_REALTIME,&stop); double run_time = (stop.tv_sec - start.tv_sec) + (double)(stop.tv_nsec - start.tv_nsec) / 1000000000.0; #if defined(VERIFY) // verify for (btree_key_t k = 0; k < MAX_KEY; ++k) { if (NULL_DATA == btree_find(tree,k)) { if (flags[k]) fprintf(stderr,"VERIFICATION ERROR: %l found, and shouldn't have been\n",k); } else { if (!flags[k]) fprintf(stderr,"VERIFICATION ERROR: %l not found, and should have been\n",k); } } #endif // clean up free_btree(tree); // report runtime if (ga_testing) fprintf(stdout,"%f",run_time); else fprintf(stdout,"\ntreebench (Std. C) run time: %f\n\n",run_time); fflush(stdout); // done return 0; }
main() { struct sockaddr_in foreign; int foreign_len = sizeof(foreign); int rval, more; static char name[] = "kpasswdd"; static struct rlimit rl = { 0, 0 }; progname = name; openlog("kpasswdd", LOG_CONS | LOG_PID, LOG_AUTH); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGTSTP, SIG_IGN); if(setrlimit(RLIMIT_CORE, &rl) < 0) { syslog(LOG_ERR, "setrlimit: %m"); exit(1); } if(getpeername(0, &foreign, &foreign_len) < 0) { syslog(LOG_ERR,"getpeername: %m"); exit(1); } strcpy(inst, "*"); rval = krb_recvauth( 0L, /* !MUTUAL */ 0, /* file desc */ &ticket, /* client's ticket */ SERVICE, /* expected service */ inst, /* expected instance */ &foreign, /* foreign addr */ (struct sockaddr_in *) 0, &kdata, "", (bit_64 *) NULL, /* key schedule */ version ); if(rval != KSUCCESS) { syslog(LOG_ERR, "krb_recvauth: %s", krb_err_txt[rval]); cleanup(); exit(1); } /* get master key */ if(kdb_get_master_key(0, master_key, master_key_schedule) != 0) { syslog(LOG_ERR, "couldn't get master key"); cleanup(); exit(1); } mkeyversion = kdb_get_master_key(master_key, master_key_schedule, NULL); if(mkeyversion < 0) { syslog(LOG_NOTICE, "couldn't verify master key"); cleanup(); exit(1); } /* get principal info */ rval = kerb_get_principal( kdata.pname, kdata.pinst, &principal_data, 1, &more ); if(rval != 1 || (more != 0)) { syslog(LOG_NOTICE, "more than 1 entry for %s.%s", kdata.pname, kdata.pinst); cleanup(); exit(1); } /* get the user's key */ bcopy(&principal_data.key_low, key, 4); bcopy(&principal_data.key_high, ((long *) key) + 1, 4); kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); key_sched(key, key_schedule); des_set_key(key, key_schedule); /* get random key and send it over {random} Kperson */ random_key(kpwd_data.random_key); strcpy(kpwd_data.secure_msg, SECURE_STRING); if(des_write(0, &kpwd_data, sizeof(kpwd_data)) != sizeof(kpwd_data)) { syslog(LOG_ERR, "error writing initial data"); cleanup(); exit(1); } bzero(key, sizeof(key)); bzero(key_schedule, sizeof(key_schedule)); /* now read update info: { info }Krandom */ key_sched(kpwd_data.random_key, random_sched); des_set_key(kpwd_data.random_key, random_sched); if(des_read(0, &ud_data, sizeof(ud_data)) != sizeof(ud_data)) { syslog(LOG_ERR, "update aborted"); cleanup(); exit(1); } /* validate info string by looking at the embedded string */ if(strcmp(ud_data.secure_msg, SECURE_STRING)) { syslog(LOG_NOTICE, "invalid update from %s", inet_ntoa(foreign.sin_addr)); cleanup(); exit(1); } /* produce the new key entry in the database { key }Kmaster */ string_to_key(ud_data.pw, key); kdb_encrypt_key(key, key, master_key, master_key_schedule, ENCRYPT); bcopy(key, &principal_data.key_low, 4); bcopy(((long *) key) + 1, &principal_data.key_high, 4); bzero(key, sizeof(key)); principal_data.key_version++; if(kerb_put_principal(&principal_data, 1)) { syslog(LOG_ERR, "couldn't write new record for %s.%s", principal_data.name, principal_data.instance); cleanup(); exit(1); } syslog(LOG_NOTICE,"wrote new password field for %s.%s from %s", principal_data.name, principal_data.instance, inet_ntoa(foreign.sin_addr) ); send_ack(0, "Update complete.\n"); cleanup(); exit(0); }
static void run_test (struct sockaddr_in *addr) { CLIENT *clnt; char value_val1[] = "Hello, world."; char value_val2[] = "Goodbye, world."; bamboo_put_args put_args; bamboo_get_args get_args; bamboo_get_res *get_result; int first; memset (&put_args, 0, sizeof (put_args)); memset (&get_args, 0, sizeof (get_args)); srand (1); clnt = connect_to_server (addr); do_null_call (clnt); // Do a first put. random_key (put_args.key, sizeof (put_args.key)); put_args.value.bamboo_value_val = value_val1; put_args.value.bamboo_value_len = sizeof (value_val1); do_put (clnt, &put_args); // Check that the data's there. memcpy (get_args.key, put_args.key, sizeof (get_args.key)); get_result = do_get (clnt, &get_args); if (get_result->values.values_len != 1) { printf ("Get failed: returned %d values.\n", get_result->values.values_len); exit (1); } if (compare_values (&(get_result->values.values_val [0]), value_val1, sizeof (value_val1)) != 0) { printf ("Get failed: values don't match: %s vs %s\n", value_val1, get_result->values.values_val [0].bamboo_value_val); exit (1); } printf ("Get successful.\n"); // Do a second put with the same key. put_args.value.bamboo_value_val = value_val2; put_args.value.bamboo_value_len = sizeof (value_val2); do_put (clnt, &put_args); // Check that both values are there. get_result = do_get (clnt, &get_args); if (get_result->values.values_len != 1) { printf ("Get failed: returned %d values.\n", get_result->values.values_len); exit (1); } printf ("Get returned value %s.\n", get_result->values.values_val [0].bamboo_value_val); if (compare_values (&(get_result->values.values_val [0]), value_val1, sizeof (value_val1)) == 0) { printf ("Get returned first value.\n"); first = TRUE; } else if (compare_values (&(get_result->values.values_val [0]), value_val2, sizeof (value_val2)) == 0) { printf ("Get second first value.\n"); first = FALSE; } else { printf ("Get failed: returned neither value.\n"); exit (1); } get_args.placemark.bamboo_placemark_val = get_result->placemark.bamboo_placemark_val; get_args.placemark.bamboo_placemark_len = get_result->placemark.bamboo_placemark_len; get_result = do_get (clnt, &get_args); if (get_result->values.values_len != 1) { printf ("Get failed: returned %d values.\n", get_result->values.values_len); exit (1); } printf ("Get returned value %s.\n", get_result->values.values_val [0].bamboo_value_val); if (first) { if (compare_values (&(get_result->values.values_val [0]), value_val2, sizeof (value_val2)) != 0) { printf ("Get failed: second value doesn't match: %s vs %s\n", value_val2, get_result->values.values_val [0].bamboo_value_val); exit (1); } } else if (compare_values (&(get_result->values.values_val [0]), value_val1, sizeof (value_val1)) != 0) { printf ("Get failed: second value doesn't match: %s vs %s\n", value_val1, get_result->values.values_val [0].bamboo_value_val); exit (1); } printf ("Get successful.\n"); // Do a put with a different key. random_key (put_args.key, sizeof (put_args.key)); do_put (clnt, &put_args); // Check that the data's there. memcpy (get_args.key, put_args.key, sizeof (get_args.key)); get_args.placemark.bamboo_placemark_val = NULL; get_args.placemark.bamboo_placemark_len = 0; get_result = do_get (clnt, &get_args); if (get_result->values.values_len != 1) { printf ("Get failed: returned %d values.\n", get_result->values.values_len); exit (1); } if (compare_values (&(get_result->values.values_val [0]), value_val2, sizeof (value_val2)) != 0) { printf ("Get failed: values don't match: %s vs %s\n", value_val2, get_result->values.values_val [0].bamboo_value_val); exit (1); } printf ("Get successful.\n"); clnt_destroy (clnt); }
void exercise19(){ // vector.push_back() is busted /* Exercise 19 */ Xstr keystream("Z/kf0FmwkR2EwZr1qdZfgqaoWbSlLy/QGY/VRRhA9LAAA===", Xstr::BASE64_ENCODED); string strings[38] = { "SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==", "Q29taW5nIHdpdGggdml2aWQgZmFjZXM=", "RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==", "RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=", "SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk", "T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==", "T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=", "UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==", "QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=", "T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl", "VG8gcGxlYXNlIGEgY29tcGFuaW9u", "QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==", "QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=", "QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==", "QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo=", "QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=", "VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA==", "VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg==", "V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw==", "V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA==", "U2hlIHJvZGUgdG8gaGFycmllcnM/", "VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w=", "QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4=", "VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ=", "V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs=", "SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA==", "U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA==", "U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=", "VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==", "QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu", "SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=", "VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs", "WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=", "SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0", "SW4gdGhlIGNhc3VhbCBjb21lZHk7", "VHJhbnNmb3JtZWQgdXR0ZXJseTo=", "QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=", }; vector<Xstr> ciphers; Xstr random_key("Rfh9orvO75Iba9PsvseQPg==", Xstr::BASE64_ENCODED); /* Make 8-byte nonce for CTR, fill with 0's * We use the same nonce for all encryptions, which is where the * weakness is */ Xstr nonce; nonce.resize(AES::CTR_NONCE_SIZE, 0); Xstr next_str; Xstr next_cipher; Xstr newstr; string s; // encrypt the strings for(int i = 0; i < 37; i++){ newstr = Xstr(strings[i], Xstr::BASE64_ENCODED); next_cipher = BlockCipher::encrypt(EncryptType::CTR_ENCRYPT, newstr, random_key, nonce); ciphers.push_back( next_cipher ); } // get keystream with partially solved characters Xstr cracked_keystream = break_fixed_nonce_CTR_by_substituting(ciphers); // I could waste my time guessing and complete the keystream, but I // have better things to do :) crypto_exercise_test(19, keystream == cracked_keystream ); }
int main() { long long start, end, duration, t1, t2; struct timeval tv; int i, j, key_size, value_buffer_size; kvs_env.init_type = INIT_TYPE_CREATE; kvs_env.disk_file_path = "disk_file"; kvs_env.IMAGE_file_path = "IMAGE_file"; kvs_env.log_file_path = "log_file"; kvs_env.buffer_sleep_time = 0; kvs_env.buffer_horizon_size = 100 * 1024 * 1024; kvs_env.buffer_size = 700 * 1024 * 1024; for (i = 0; i < VALUE_BUFFER_SIZE; i++) value_buffer[i] = 'a'; srand((unsigned) time(NULL)); gettimeofday(&tv, NULL); start = tv.tv_sec * 1000 * 1000 + tv.tv_usec; if (kv_init(&kvs_env) != 0) { printf("kvs_init fail\n"); return -1; } //first write 5GB for (i = 0; i < CNT; i++) { get_key(key_buffer, i, &key_size); if (kv_put(key_buffer, key_size, value_buffer, VALUE_BUFFER_SIZE) != 0) { printf("kv_put fail\n"); return -1; } } duration = 0; j = CNT; for (i = 0; i < CNT; i++) { get_key(key_buffer, j, &key_size); if (i % 200 == 0) { if (kv_put(key_buffer, key_size, value_buffer, VALUE_BUFFER_SIZE) != 0) { printf("kv_put fail\n"); return -1; } j++; } random_key(key_buffer, j - 1, &key_size); gettimeofday(&tv, NULL); t1 = tv.tv_sec * 1000 * 1000 + tv.tv_usec; if (kv_get(key_buffer, key_size, value_buffer, &value_buffer_size) != 0) { printf("kv_get fail\n"); return -1; } gettimeofday(&tv, NULL); t2 = tv.tv_sec * 1000 * 1000 + tv.tv_usec; duration += (t2 - t1) / 1000; } kv_exit(); printf("read time: %lld ms\n", duration); gettimeofday(&tv, NULL); end = tv.tv_sec * 1000 * 1000 + tv.tv_usec; duration = (end - start) / 1000; printf("total time: %lld ms\n", duration); return 0; }