学校作业的简单密码加密方法

3
好的,我正在为一门大学课程构建一个程序,它是一个简单的程序,使用结构来模拟建立一个用户信息数据库,包括用户名和密码。在实验中可以加分,我们可以对密码进行加密。这并不是什么特别的事情……我们没有使用MD5或其他高级技术。
我只需要能够将大写字母转换为小写字母,将小写字母转换为大写字母,最后,我遇到问题的部分是将十进制整数转换为十六进制。
我将尝试发布程序的相关部分而不是整个程序。
以下是结构:
struct Info
{
    string sFname;
    string sLname;
    string sUname;
    string sPword;
    string sAddress;
    string sEmail;
    string sPhone;
};

注意:这是一个结构体的动态数组。
Info *Users;
        Users = new Info[size];

这是我目前编写的加密密码代码:

//string length for controlling loops
strlen = Users[iUsrCount].sPword.length();

        //temp string to hold the encrypted version of password
        string temp;

        //switch uppercase characters to lowercase and vice versa, and convert
        //decimal integers into hexadecimal
        for(int i=0; i<strlen; i++)
        {
                cout << "\n\nInside encryption for loop iteration " << i << "\n\n";

                if(islower(Users[iUsrCount].sPword[i]))
                {
                        temp += toupper(Users[iUsrCount].sPword[i]);
                        continue;
                }
                else if(isupper(Users[iUsrCount].sPword[i]))
                {
                        temp += tolower(Users[iUsrCount].sPword[i]);
                        continue;
                }
                else if(isdigit(Users[iUsrCount].sPword[i]))
                {
                        char charNum = Users[iUsrCount].sPword[i];
                        int iDec = charNum - '0';



                        //get integer
                        while((i+1) < strlen && isdigit(Users[iUsrCount].sPword[i+1]))
                        {
                                i++;
                                iDec = iDec * 10 + Users[iUsrCount].sPword[i] - '0';
                                cout << " " << iDec << " ";
                        }

                        char hexTemp[10];

                        //convert
                        sprintf(hexTemp, "%x", iDec);

                        temp += hexTemp;

                        //debugging cout to make sure hexes are properly calculated
                        cout << " " << hexTemp << " ";
                        continue;
                }
        }
                //debugging cout to make sure that password is properly encrypted
                cout << endl << endl << temp << endl << endl;

                strlen = temp.length();

                //overwrite the plain text password with the encrypted version
                for(int i=0; i<strlen; i++)
                        Users[iUsrCount].sPword[i] = temp[i];

                //debugging cout to make sure copy was successful
                cout << endl << endl << Users[iUsrCount].sPword;

因此,如果您的密码是:

456Pass45word87

加密后的内容将如下所示:

1c8pASS2dWORD57

我们还需要翻转字符串,但这相当简单。我的两个问题是:
1. 有没有更简单的方法?
2. 我怎么也想不出正确的算法来解密密码,我需要这样做,以便用户登录时,计算机可以将他们输入的内容与其密码的明文版本进行比较。
注意:我绝不是专业的编码人员,所以请对新手仁慈,尽量不要让我太超前。我已经到处找过,但我找不到任何真正帮助我解决特定情况的东西。因此,我把自己投入了互联网的怀抱。 :D

6
永远不应该解密密码,只需对用户输入的密码进行加密,然后再次加密并将其与已加密的密码进行比较。 - allejo
1
完全同意allejo的观点。尽管如此,由于这只是一个作业,了解如何反转加密过程仍然具有教育意义。你需要做的是将加密过程逆转。例如,首先反转字符串,将大写字母转换为小写字母,反之亦然,然后将十六进制转换回十进制形式。 - greatwolf
1
这并不是真正的加密算法,因为它是不可逆的。'ab' 可能意味着输入是 'AB',也可能意味着输入是 '171'。 - David Schwartz
思考异或运算是如何工作的。例如,观察当你用ASCII字符集中的字符与空格字符进行异或运算时会发生什么。 - Carey Gregory
我真的想不出正确的算法来解密密码。为什么?考虑一下:123AbCd加密后变成了7baBcD。你怎么知道a不再是你的密码的一部分了呢?你需要像分隔符这样的东西。因此,即使考虑到解密的教育价值,我仍然会选择allejo的方法。 - Kiruse
3个回答

1
  1. 有没有更简单的方法做这件事?

-- 你的方法对我来说很好。你的方式清晰易懂。

  1. 我无论如何都想不出正确的算法来解密密码,但我需要这样做,以便当用户登录时,计算机可以将他们输入的内容与他们密码的明文版本进行比较。

-- 你不应该尝试解密密码。当用户登录时,使用加密后的密码进行比较。


如何比较密码不是问题的关键。 - Carey Gregory
@CareyGregory Colt 所说的一个例子是,密码 ABC 在加密后可能变成 233dweww,由于加密方法不会改变,因此 ABC 总是会变成 233dweww,所以你应该测试 encPassword = encrypt(unencPassword);,其中 unencPassword 是用户输入的未加密密码,而 encPassword 是他们存储和加密的密码 :) - Matthew Pigram
@MatthewPigram - 我明白,但请再读一遍问题。这是一个学生的作业问题。范围非常有限,并不期望得到专业水平的解决方案。只需要知道如何加密和解密。 - Carey Gregory

0

使用boost和C++11有更简单的方法,但如果您不介意使用普通的C++98,则可以使用STL和一元函数来完成此操作

#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <sstream>
#include <cctype>
#include <vector>
#include <iterator>
using namespace std;

//modified from here:
//https://dev59.com/03RC5IYBdhLWcg3wYf8p#313990
char flipcase (char in) {
    if (in<='Z' && in>='A')
        return in-('Z'-'z');
    else if (in<='z' && in>='a') {
        return in+('Z'-'z');
    }
    return in;
}

int main() {
    string test = "456Pass45word87";
    transform(test.begin(), test.end(), test.begin(), flipcase);//this flips uppercase to lowercase and vice-versa

    string nums, text;
    vector<string> parts;

    //break the string into its constituent number and textual parts and operate
    //on them accordingly.
    //for text, store all until a non-text character is reached. Reset.
    //for numbers, keeping iterating until the first non-digit character
    //is reached. Store, then reset.
    for (int i = 0; i < test.length(); i++) {
        if (isdigit(test[i])) {
            nums += test[i];
            if (!text.empty()) {
                parts.push_back(text);//store the text
            }
            text.clear();//reset the memory in it
        }
        else {
            text += test[i];

            if (!nums.empty()) {                
                int n = atoi(nums.c_str());
                stringstream ss;
                //now reinsert back into the string stream and convert it to a hexadecimal:
                ss << std::hex << n;

                parts.push_back(ss.str());//now store it
                nums.clear();//clear the number string
            }
        }
    }

    //at this point the vector contains the string broken into different parts
    //that have been correctly modified.
    //now join all the strings in the vector into one:
    //adapted from here:
    //https://dev59.com/BG025IYBdhLWcg3w_a-r#5689061
    ostringstream oss;
    copy(parts.begin(), parts.end(), ostream_iterator<string>(oss,""));//we want no character delimiter between our strings
    cout << oss.str();

    return 0;
}

这将打印:

1c8pASS2dWORD57

按照要求。

注意:

当迭代字符串时,您可以使用迭代器,但这是您自己可以做的事情。

参考文献:

https://dev59.com/03RC5IYBdhLWcg3wYf8p#313990

https://dev59.com/BG025IYBdhLWcg3w_a-r#5689061

http://www.cplusplus.com/reference/algorithm/transform/


0

对于您的加密,您已将以下内容设置为参数:

//switch uppercase characters to lowercase and vice versa, and convert
//decimal integers into hexadecimal

所以要解密,您只需要反转这个过程:

  • 将十六进制转换为十进制
  • 将大小写转换为相反的大小写

这样就可以得到解密后的版本。

如果您需要更多细节,请告诉我,我可以在今天某个时间尝试帮忙。


我理解我必须反转这个过程,但仅将十进制转换为十六进制比我预期的要复杂得多。我一直在困惑如何正确地反转算法。我可能会像之前建议的那样比较加密后的密码,因为这可以避免我一开始就进行解密,但我仍想知道如何实现它,只是为了增加知识。 - Warren Smith
如果你反转加密代码(数学符号/顺序),那么它将为你解密加密的密码 :) 当我有时间时,我会找出一个解决方案并为你发布更多信息 :) - GMasucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接