首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的散列程序不能通过测试?

为什么我的散列程序不能通过测试?
EN

Stack Overflow用户
提问于 2021-12-30 20:26:13
回答 1查看 103关注 0票数 -1

任务:

要在系统中注册,每个居民必须提供一个密码。密码包括拉丁字母(大写和小写)的字母,以及从0到9的数字,也就是说,总共可以使用62个字符。密码长度为5至20个字符。密码以加密的形式存储在数据库中,按照以下算法进行加密:

  1. 是大写拉丁字母的数字b。对于密码中的每个大写字母字符,由bb字符执行循环右移(例如,如果是b=3,则D字符转换为G字符,对于密码中的每个小写字符,Y字符转换为B字符,向右的循环移位由m个字符执行,其中m是密码中小写字母的数目。

)

为了快速搜索数据库中的用户,将使用以下算法为每个加密密码计算一个散列函数:

  1. 所有62个字符都是有序的,首先是数字,然后是小写字母,然后是大写字母。
  2. 为每个字符分配了一个代码--这个序列中的字符数,从0开始。因此,数字码与它们的值相匹配,小写字母代码a-10,b-11等等。
  3. 所有代码被求和,其馀的和s除以数字p和q,得到的数字对(s mod p,s mod q)将是散列函数的值。

如果很少发生冲突,则哈希函数被认为是很好的,也就是说,函数的值与不同的密码匹配。

约翰想出了一个新密码。同时,数据库中已经有nn密码,我希望避免冲突。约翰会成功吗?

输入数据

第一行包含一个表示John密码的字符串。第二行包含一个整数n-数据库中的密码数。第三行包含整数p和q。下面的行以未加密的形式存储密码。

输出数据

整数是其哈希函数与John的密码的散列函数匹配的密码数。

样本输入:

AabB1cd

5

13 . 17

Nik143pasw

qeAom1

q1w2e3r4t

aBoba2012

N33iEj

样本输出:

2

注意:

与John的散列函数匹配的密码将被高亮显示。

约翰密码的处理:循环移位后: CefD1gh (大写字母移2,小写4)字符码之和为38+14+15+39+1+16+17=140,散列函数等于(10,4)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-30 20:53:47

您的代码中有一些逻辑问题。当您将大写字符和小写字符旋转到它们的“加密”形式时,您会迭代密码两次,有时还会错误地旋转字符。举个例子,就这一行

代码语言:javascript
复制
if (pas[i] + big >= 'A' && pas[i] + big <= 'Z') pas[i] = pas[i] + big;

考虑一下pas[i] == '9'big == 8的情况。最后,您将把所有的9转换为A

现在考虑下一个循环中的行

代码语言:javascript
复制
if (pas[i] + small >= 'a' && pas[i] + small <= 'z') pas[i] = pas[i] + small;

如果small足够大,它同样会把一些大写字母转换成小写字母。

你也可以把这两个问题结合起来。假设pas[i]最初是Ybig是1,little是7。您将转换Y --> Z,然后在下一步转换Z --> a

  1. Compartmentalize并将单个大型主函数抽象为较小的函数块。这将允许您对每个部分进行单独的推理,而不是试图将main()的全部内容保留在您的头脑中。人类的短期记忆有限。--

一些建议的职能将包括

在转换步骤中循环两次密码的

  • bool is_upper(char c)
  • bool is_lower(char c)
  • bool is_numeric(char c)
  • char rotate_upper(char c, int steps)
  • char rotate_lower(char c, int steps)
  1. Instead,考虑循环一次密码。如果字符大写,则相应地进行转换。如果是小写,则相应地进行转换。这将阻止你重复旋转一些数字。

将上述所有内容结合在一起,主函数的两个加密循环可能会从以下几个方面转变:

代码语言:javascript
复制
for (int i = 0; i < pas.length(); i++)
    {
        if (pas[i] + big >= 'A' && pas[i] + big <= 'Z') pas[i] = pas[i] + big;
        else if (pas[i] >= 'A' && pas[i] <= 'Z') {
            int tempVar = big;
            while (tempVar > 0) {
                if (pas[i] == 'Z') {
                    pas[i] = 'A';
                    tempVar = tempVar - 1;
                }
                tempVar = tempVar - 1;
                pas[i] = pas[i] + 1;
            }
        }
    }
    for (int i = 0; i < pas.length(); i++)
    {
        if (pas[i] + small >= 'a' && pas[i] + small <= 'z') pas[i] = pas[i] + small;
        else if (pas[i] >= 'a' && pas[i] <= 'z') {
            int tempVar = small;
            while (tempVar > 0) {
                if (pas[i] == 'z') {
                    pas[i] = 'a';
                    tempVar = tempVar - 1;
                }
                pas[i] = pas[i] + 1;
                tempVar = tempVar - 1;
            }
        }
    }

代码语言:javascript
复制
for (int i = 0; i < pas.length(); i++) {
    char c = pas[i];
    if (is_upper(c)) {
        pas[i] = rotate_upper(c, big);
    }
    else if (is_lower(c)) {
        pas[i] = rotate_lower(c, small);
    }
}

您可以将30行代码转换为10行以下的代码,这对于您、开发人员和任何潜在的评审人员来说都要容易得多。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70536361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档