以下是TEA的实现,它尝试加密包含文本消息的文件:
main.cpp
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include "TEA.h"
int main()
try
{
// std::cout <<"sizeof(long) = " << sizeof(long) <<'\n';
std::string src("in.txt");
std::string dest("out.txt");
std::string key("bs");
send_msg(src, dest, key);
}
catch(std::exception& e)
{
std::cerr << e.what();
exit(1);
}
TEA.h
#ifndef TEA_h
#define TEA_h
/*
src - eight (2 words or 2*4 bytes) characters to be enciphered.
dest- enciphered output.
key - array of 4 words.
Assumes sizeof(long) == 4 bytes.
*/
void encipher(const unsigned long* const v,
unsigned long* const w,
const unsigned long* const k)
{
unsigned long y = v[0];
unsigned long z = v[1];
unsigned long sum = 0;
unsigned long delta = 0x9E3779B9;
unsigned long n = 32;
while (n-- > 0)
{
y += (z<<4 ^ z>>5) + z^sum + k[sum&3];
sum += delta;
z += (z<<4 ^ z>>5) + y^sum + k[sum>>11&3];
}
w[0] = y;
w[1] = z;
}
//---------------------------------------------------------------------------
/*
Sends the clear text from: src_file as
encrypted text to: dest_file, using TEA
with key: the last argument.
*/
void send_msg(std::string& src_file,
std::string& dest_file,
std::string key)
{
const int nchar = 2 * sizeof(long); // size of I/O chunk: 8 bytes = 64 bits
const int kchar = 2 * nchar; // size of key: 16 bytes = 128 bits
// pad key with 0's to match en-/de- cipher argument input size
while (key.size() < kchar)
{
key += '0';
}
// prepare files
std::ifstream ifs(src_file.c_str());
std::ofstream ofs(dest_file.c_str());
if (!ifs || !ofs)
{
throw std::runtime_error("File can't open!\n");
}
// key: extract raw string data interpreted as pointer to const unsigned long
const unsigned long* k = reinterpret_cast<const unsigned long*>(key.data());
// define C-compatible way to read & write from / to file 128 bits (two unsigned longs) at a time
unsigned long outptr[2];
char inbuf[nchar];
unsigned long* inptr = reinterpret_cast<unsigned long*>(inbuf);
int count = 0;
while (ifs.get(inbuf[count]))
{
ofs << std::hex; // write output in hex
if (++count == nchar) // 8 characters in the input buffer: ready to encode
{
encipher(inptr, outptr, k);
// pad with leading 0's
ofs << std::setw(8) << std::setfill('0') << outptr[0] <<' '
<< std::setw(8) << std::setfill('0') << outptr[1] <<' ';
count = 0;
}
}
if (count) // pad at the end
{
while (count != nchar)
{
inbuf[count++] = '0';
}
encipher(inptr, outptr, k);
ofs << outptr[0] <<' '<< outptr[1] <<' ';
}
}
#endif
输入文件in.txt
:
The Tiny
预计在输出文件中:
5b8fb57c 806fbcce
输出文件中的实际值out.txt
:
f3a810ff 3874d755
我做错了什么?
答案 0 :(得分:4)
+
操作的优先级高于^
,因此(z<<4 ^ z>>5) + z^sum + k[sum&3]
被解析为
(((z<<4) ^ (z>>5)) + z)^(sum + k[sum&3]).
与其他表达相似。
您应该添加括号以使表达式在其执行方式中明确。
答案 1 :(得分:0)
问题确实与那些表达式有关(由@ 1201ProgramAlarm指出),但是,它与(错误的)隐式运算符优先级(也不是arity)无关。
y += (z<<4 ^ z>>5) + z^sum + k[sum&3];
sum += delta;
z += (z<<4 ^ z>>5) + y^sum + k[sum>>11&3]; // <------ the problem is here
左右位移操作必须应用于变量y
,即:
z += (y<<4 ^ y>>5) + y^sum + k[sum>>11&3];