1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <exception>
void encipher(
const unsigned long* const v,
unsigned long* const w,
const unsigned long* const k)
{
static_assert(sizeof(long) == 4, "size of long wrong for TEA");
unsigned long y = v[0];
unsigned long z = v[1];
unsigned long sum = 0;
const unsigned long delta = 0x9E3779B9;
for (unsigned long n = 32; n-- > 0; ) {
y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3];
sum += delta;
z += (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3];
}
w[0] = y;
w[1] = z;
}
//*****************************************************
void decipher(
const unsigned long* const v,
unsigned long* const w,
const unsigned long* const k)
{
static_assert(sizeof(long) == 4, "size of long wrong for TEA");
unsigned long y = v[0];
unsigned long z = v[1];
unsigned long sum = 0xC6EF3720;
const unsigned long delta = 0x9E3779B9;
// sum = delta<<5, in general sum = delta * n
for (unsigned long n = 32; n-- > 0; ) {
z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3];
sum -= delta;
y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3];
}
w[0] = y;
w[1] = z;
}
//*****************************************************
int main() try
{
const int nchar = 2 * sizeof(long); // 64 bits
const int kchar = 2 * nchar; // 128 bits
//std::cout << nchar << ' ' << kchar << '\n';
std::string op;
std::string key;
std::string infile;
std::string outfile;
std::cout << "please enter input file name, output file name, and key:\n";
std::cin >> infile >> outfile >> key;
while (key.size() < kchar) key += '0'; // pad key
std::ifstream inf(infile);
std::ofstream outf(outfile);
if (!inf || !outf) throw("bad file name");
const unsigned long* k = reinterpret_cast<const unsigned long*>(key.data());
unsigned long outptr[2];
char inbuf[nchar];
unsigned long* inptr = reinterpret_cast<unsigned long*>(inbuf);
int count = 0;
while (inf.get(inbuf[count])) {
outf << std::hex; // use hexadecimal output
if (++count == nchar) {
encipher(inptr, outptr, k);
// pad with leading zeros:
outf << std::setw(8) << std::setfill('0') << outptr[0] << ' '
<< std::setw(8) << std::setfill('0') << outptr[1] << ' ';
count = 0;
}
}
if (count) { // pad
while (count != nchar) inbuf[count++] = '0';
encipher(inptr, outptr, k);
outf << outptr[0] << ' ' << outptr[1] << ' ';
}
system("pause");
return 0;
}
catch (std::invalid_argument& e) {
std::cerr << e.what() << '\n';
abort();
}
|