我想将函数名从弱嵌入式系统发送到主机以进行调试。由于两者是通过带宽短的RS232连接的,我不想直接发送功能的名称。有大约15个字符长的函数名称,我有时想以相当高的速率发送这些名称。
我想到的解决方案是找到一个散列函数,它将这些函数名称散列为单个字节,并仅发送此字节。主机将扫描源中的所有函数,使用相同的函数计算它们的哈希值,然后将哈希值转换为原始字符串。
哈希函数必须是
显然,它不需要以任何方式保证安全,只有无碰撞。因此,我不认为使用与加密相关的哈希函数是值得的复杂性。
示例代码:
int myfunc() {
sendToHost(hash("myfunc"));
}
然后主持人可以向我提供执行myfunc
功能的时间列表。
是否有一些已知的哈希函数可以保持上述条件?
修改
答案 0 :(得分:8)
答案 1 :(得分:3)
嗯只有256个可能的值,因为你将解析你的源代码以了解所有可能的函数,也许最好的方法是将一个数字归属于你的每个函数???
真正的哈希函数可能不会起作用,因为你只有256个哈希值。 但是您希望映射至少26 ^ 15个可能的值(假设仅限字母,不区分大小写的函数名称)。 即使你限制了可能的字符串数量(通过应用一些强制格式化),你也很难获得有意义的名字和有效的哈希函数。
答案 2 :(得分:3)
不,没有。
您只能使用8位哈希来制作无冲突的哈希码,甚至不接近它。如果允许长度超过一个字符的字符串,则可能的字符串多于可能的哈希码。
为什么不提取函数名称并给每个函数名称一个id?那么你只需要在电线的每一侧都有一个查找表。
(正如其他人已经表明,如果您已经拥有所有函数名称,则可以生成没有冲突的哈希算法,但是更容易为每个名称分配一个数字以生成查找表...)
答案 3 :(得分:3)
您可以使用Huffman tree根据程序中使用的频率缩写功能名称。最常见的函数可以缩写为1位,不太常见的函数可以缩写为4-5,非常罕见的函数可以缩写为10-15位等。霍夫曼树不是很难实现,但你必须对位对齐做一些事情。
答案 4 :(得分:2)
如果您有办法跟踪代码中的函数(即在运行时生成的文本文件),您可以使用每个函数的内存位置。不完全是一个字节,但小于整个名称并保证是唯一的。这具有低开销的额外好处。你需要“解码”地址的只是将地址映射到实际名称的文本文件;这可以发送到远程位置,或者,正如我所提到的,存储在本地计算机上。
答案 5 :(得分:0)
在这种情况下,您可以使用enum
来识别功能。在某个头文件中声明函数ID:
typedef enum
{
FUNC_ID_main,
FUNC_ID_myfunc,
FUNC_ID_setled,
FUNC_ID_soundbuzzer
} FUNC_ID_t;
然后在函数中:
int myfunc(void)
{
sendFuncIDToHost(FUNC_ID_myfunc);
...
}
答案 6 :(得分:0)
如果发送方和接收方共享同一组函数名,则可以从这些函数名构建相同的哈希表。您可以使用获取哈希元素的路径来进行通信。这可以是{起始位置+跳数}来传达此信息。这将占用2个字节的带宽。对于固定大小的表(lineair探测),只需要最终索引来处理条目。
注意:构建两个“同步”哈希表时,插入顺序很重要; - )
答案 7 :(得分:0)
这里描述的是一种自己实现它的简单方法:http://www.devcodenote.com/2015/04/collision-free-string-hashing.html
以下是该帖子的摘录:
它的灵感来源于二进制数被解码并转换为十进制数格式的方式。每个二进制字符串表示唯一地映射到十进制格式的数字。
如果我们有一个大写英文字母的字符集,那么字符集的长度是26,其中A可以用数字0表示,B表示数字1,C表示数字2,依此类推,直到Z现在,每当我们想要将这个字符集的字符串映射到一个唯一的数字时,我们就会执行与二进制格式相同的转换