【问题标题】:Simple Password Encryption for school assignment学校作业的简单密码加密
【发布时间】:2013-11-14 17:37:18
【问题描述】:

好的,我正在为大学课程构建一个程序,它是一个简单的程序,它使用结构来模拟构建用户信息以及用户名和密码的数据库。对于实验室的额外信用,我们可以加密密码。这没什么特别的……我们没有使用 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

我们还必须反转字符串,但这很简单。

我的 2 个问题是这样的:

  1. 有没有更简单的方法来做到这一点?

  2. 在我的一生中,我无法找出正确的算法来解密密码,我需要这样做,以便当用户登录时,计算机可以将他们键入的内容与纯文本进行比较他们的密码版本。

注意:我绝不是专业的编码员,所以请对菜鸟手下留情,尽量不要对我太超前。我找遍了整个地方,但找不到任何对我的具体情况真正有帮助的东西。

因此,我将自己置于互联网的摆布之下。 :D

【问题讨论】:

  • 您永远不应该解密密码,只需将他们输入的密码加密并加密,然后将其与加密后的密码进行比较。
  • 完全同意 allejo。尽管如此,由于这只是一个知道如何反转加密过程的任务,因此仍然具有教育意义。您需要做的是向后应用加密过程。例如。首先反转字符串,从大到小反之亦然,然后将十六进制转换回十进制形式。
  • 这不是真正的加密算法,因为它是不可逆的。 “ab”可能意味着输入是“AB”,也可能意味着输入是“171”。
  • 考虑异或的工作原理。例如,当您使用空格字符对 ASCII 字符集中的字符进行异或运算时,这些字符会发生什么情况。
  • 我一辈子都想不出正确的算法来解密密码。为什么?考虑:123AbCd 加密:7baBcD 你怎么知道a 不再是你密码的一部分?你需要像分隔符这样的东西。因此,即使在解密的教育价值方面,我仍然会采用 allejo 的方法。

标签: c++ encryption passwords hex


【解决方案1】:

对于您的加密,您设置了以下参数:

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

所以要解密,你所要做的就是扭转循环:

  • 将十六进制转换为十进制
  • 将情况切换到相反的情况

你会得到解密的版本。

如果您需要更多详细信息,请告诉我,我今天可以尝试提供帮助。

【讨论】:

  • 我知道我必须颠倒这个过程,但是将十进制转换为十六进制比我预期的要复杂。我无法弄清楚如何正确地反转算法来做到这一点。我可能只是比较前面建议的加密密码,因为这样一开始我就不必解密,但我还是想知道怎么做,只是为了知识。
  • 如果您反转您的加密代码(数学符号/顺序),它将为您解密加密的密码:) 当我有时间时,我将制定解决方案并为您发布更多信息:)跨度>
【解决方案2】:

使用 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://stackoverflow.com/a/313990/866930
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://stackoverflow.com/a/5689061/866930
    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://stackoverflow.com/a/313990/866930

https://stackoverflow.com/a/5689061/866930

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

【讨论】:

    【解决方案3】:
    1. 有没有更简单的方法可以做到这一点?

    -- 你的方法对我来说似乎很好。你的方法足够清晰和容易。

    1. 在我的一生中,我无法找出正确的算法来解密密码,我需要这样做,以便当用户登录时,计算机可以将他们输入的内容与他们的纯文本版本进行比较密码。

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

    【讨论】:

    • 如何比较密码不是问题。
    • @CareyGregory Colt 意思的一个例子是密码 ABC 在加密后可能变为 233dweww,ABC 将始终变为 233dweww,因为加密方法没有改变,所以你应该测试 encPassword = encrypt(unencPassword); 其中 unencPassword 是什么用户正在输入并且 encPassword 是他们存储和加密的密码:)
    • @MatthewPigram - 我明白,但重新阅读这个问题。这是一个学生的家庭作业问题。它的范围非常有限,并且不期望专业级别的解决方案。如何加密和解密,仅此而已。
    猜你喜欢
    • 2010-09-07
    • 1970-01-01
    • 2020-01-31
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 2017-08-10
    相关资源
    最近更新 更多