字符串上的反摘要操作总是返回相同的值
Anti-Digest operation on string always returning the same value
我正在寻找某种方法来"摘要"字符串,但总是返回相同的32(或64)字节长的值(作为十六进制字符串或纯字符)。类似以下代码的操作:
std::string digest(const std::string& input)
{
std::string result = "";
// do something with the input string, update result accordingly
return result;
}
还有更多的细节:我想要与经典摘要函数完全相反的功能,即对于每个不同的字符串,它返回一个不同但总是相同的(1比1)值。我想要一个函数,它为每个字符串每次返回相同的值(n到1)。
显然,每次返回相同常量result
的"简单"解决方案不被视为解决方案:)代码实际上应该消化输入字符串,并作为操作的结果构建result
。
举个例子:
digest ("fox") == digest ("whale")
应该是真的。
或者从数学上讲:
对于∀a和b如果a!=b=>摘要(a)==摘要(b)。这就是为什么我称之为反消化。
一个长的数学演示
您的要求是:
a!=b => digest(a)==digest(b)
让我们取另一条消息——任何其他消息c,并假设它与a和b不同:
a!=c => digest(a)==digest(c)
b!=c => digest(b)==digest(c)
从中可以看出,对于任何c,摘要都是恒定的,除非它等于a或b。
现在拿另一条消息x不管它可能是什么:
c!=x => digest(c)==digest(x)
通过对抗这个含义,这相当于:
digest(x)!=digest(c) => c==x
因此,假设有一个x,它的摘要不同于常量摘要(c)。我们有:
digest(x)!=digest(c) and digest(x)!=digest(a)
=> x==c and x==a
=> c==a
=> digest(c)!=digest(a)
但这与关于a,c,digest(a)和digest(c)的原始假设相矛盾,所以不可能有这样的x。所以你可以得出结论,你的digest必须是一个严格恒定的函数
现在假设你的函数不是恒定的:
digest(x)!=digest(a) => x==a
但如果digest是一个函数,那么它将始终为相同的输入返回相同的结果,这意味着x==a=>digest(x)==digest(a)。这表明,除了常数函数之外,没有其他解决方案。
简而言之,在C++中
函数将为相同的参数返回相同的结果,除非有副作用(静态变量或其他什么)。在只有一个参数的函数中,您要求对不同的值具有相同的结果,但对相同的值具有不同的结果是不可行的。
我似乎不清楚自己想要实现什么。。。
无论如何,我想出了以下方法:
static const size_t DIGEST_SIZE = 32;
std::string antiDigest(const std::string& a)
{
if(a.empty()) { throw "cannot digest empty string"; }
char r[DIGEST_SIZE ] = {0};
int block_size = std::min(DIGEST_SIZE, a.length());
int block_count = 1 + DIGEST_SIZE / a.length();
for(int i=0; i<block_size; i++)
{
int hlp = 0, bc = 0;
while(bc < block_count)
{
int idx = i + bc * block_size;
if(idx >= a.length()) break;
hlp += a[idx];
bc ++;
}
hlp = (int)(hlp << 3) + hlp;
unsigned int hlp2 = 0;
while(hlp)
{
int t = hlp - ((hlp/10) * 10);
hlp2 += t;
hlp /= 10;
}
bc = 0;
while(bc < block_count)
{
int idx = i + bc * block_size;
if(idx >= DIGEST_SIZE) break;
r[idx] = ( (hlp2 / 10) + (hlp2-(hlp2/10)*10)) ;
bc++;
}
}
std::stringstream result;
for(int i=0; i<DIGEST_SIZE; i++)
{
result << int_to_hex(r[i]) ;
}
return result.str();
}
在ideone上:http://ideone.com/t4dibL
显然,用逐位运算代替数学运算会使这一点更加模糊,但为了验证概念,这一点确实有效
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 如何将操作委托给函数返回
- 是否有一个C++函数可以准确返回平方根反比的内置 CPU 操作 RSQRTSS 的值?
- 复制构造函数、按值传递和按值返回、链式操作、编译器
- 如何仅覆盖一个EXPECT_CALL的默认ON_CALL操作,并在以后返回到默认操作
- 如何检查正确操作数以通过参考返回功能
- 返回指向操作+的结果的指针
- 尝试修改 sqlite3 插入以返回 PK。 不确定如何使用 sqlite3 专门执行此操作
- 在我的Matrix4类中使用某些用户定义的运算符的操作正在返回高值的高值
- 继承的加法赋值操作,如何返回正确的类型
- 堆栈弹出操作是否可以安全地返回 C++11 中的值
- 为什么计数和擦除等unordered_set操作会返回size_type
- 对向量进行操作后返回时出错
- C++类函数返回值 VS 对本地数据进行操作
- 通过互操作调用方法,该方法返回结构的实例
- C++ STL容器集和多集:不同返回类型的插入操作
- 在以下代码中执行删除操作时,我无法获得以下代码中返回的正确值
- 如何在返回SQLite中零项的SELECT操作中获取列名
- QDialog show()后面跟着返回结果操作
- 字符串上的反摘要操作总是返回相同的值