首页 > 解决方案 > 如何修复 C++ 中的“架构 x86_64 的未定义符号:”错误?

问题描述

我正在为一个类编写一个程序,该类应该破解已使用 unix 函数“crypt”加盐和加密的密码。密码可以是单词+数字或数字+单词的形式,其中数字的长度最多为三位。我们应该能够找到的示例密码如下:ant123、1ant、ant22、99ant 等。

我已经编写了一个可以正确执行此操作的程序,但现在我们应该使用 Open MPI 来加速它。在我尝试实现我的 Open MPI 代码之前它编译得很好,但现在它给了我一个错误。

我正在尝试编译,mpic++ -std=c++11 -Wall main.cc但我得到的错误是:

Undefined symbols for architecture x86_64:
  "file_IO(int, char**, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&)", referenced from:
      _main in main-33a67e.o
     (maybe you meant: __Z7file_IOiPPcRNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEESB_SB_SB_)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

主.cc:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <unistd.h>
    #include <mpi.h>

    using namespace std;

    void file_IO(int argc, char *argv[], vector<string> &encPass, vector<string> &words,
                vector<string> &salts);

    void build_guesses(vector<string> &guesses, vector<string> &words);
    void crack(string pass, vector<string> &salts, vector<string> &guesses);

    void broadcast_receive(vector<string> &encPass, vector<string> &words, vector<string> &salts,
                           vector<string> &guesses, int numProcesses, int procNum);

    vector<char> convert(vector<string> &strings);

    int main(int argc, char *argv[]) {
        vector<string> encPass;
        vector<string> words;
        vector<string> salts;
        vector<string> guesses;

        int numProcesses;
        int procNum;

        MPI_Init(NULL, NULL);

        MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
        MPI_Comm_rank(MPI_COMM_WORLD, &procNum);

        if(procNum == 0) {
            file_IO(argc, argv, encPass, words, salts);
            build_guesses(guesses, words);
        }

        else {
            broadcast_receive(encPass, words, salts, guesses, numProcesses, procNum);

            for(size_t i = 0; i < encPass.size(); i++) {
                size_t del = encPass[i].rfind("$");
                string pass = encPass[i].substr(del);
                crack(pass, salts, guesses);
            }
        }

        MPI_Finalize();
        return 0;
    }


    void file_IO(int argc, char *argv[], vector<string> &encPass, vector<string> &words,
                vector<string> &salts, vector<string> &passwords) {

        if(argc < 3) {
            cout << "One or more files were not specified." << endl;
            cout << "Correct format is './a.out file1 file2'" << endl;
            exit(1);
        }

        ifstream secretPass(argv[1]);
        string singlePass;

        while(getline(secretPass, singlePass)) {
            encPass.push_back(singlePass);
        }

        secretPass.close();

        ifstream dictionary(argv[2]);
        string word;

        while(getline(dictionary, word)) {
            words.push_back(word);
        }

        dictionary.close();

        ifstream salt("salts");
        string s;

        while(getline(salt, s)) {
            salts.push_back(s);
        }

        salt.close();
    }

    void build_guesses(vector<string> &guesses, vector<string> &words) {
        //one word and one number
        for(size_t i = 0; i < words.size(); i++) {
            for(size_t j = 0; j < 10; j++) {
                guesses.push_back(words[i] + to_string(j));
            }
        }

        //one number and one word
        for(size_t i = 0; i < 10; i++) {
            for(size_t j = 0; j < words.size(); j++) {
                guesses.push_back(to_string(i) + words[j]);
            }
        }

        //one word and two numbers
        for(size_t i = 0; i < words.size(); i++) {
            for(size_t j = 0; j < 10; j++) {
                for(size_t x = 0; x < 10; x++) {
                    guesses.push_back(words[i] + to_string(j) + to_string(x));
                }
            }
        }

        //two numbers and one word
        for(size_t i = 0; i < 10; i++) {
            for(size_t j = 0; j < 10; j++) {
                for(size_t x = 0; x < words.size(); x++) {
                    guesses.push_back(to_string(i) + to_string(j) + words[x]);
                }
            }
        }

        //one word and three numbers
        for(size_t i = 0; i < words.size(); i++) {
            for(size_t j = 0; j < 10; j++) {
                for(size_t x = 0; x < 10; x++) {
                    for(size_t y = 0; y < 10; y++) {
                        guesses.push_back(words[i] + to_string(j) + to_string(x) + to_string(y));
                    }
                }
            }
        }

        //three numbers and one word
        for(size_t i = 0; i < 10; i++) {
            for(size_t j = 0; j < 10; j++) {
                for(size_t x = 0; x < 10; x++) {
                    for(size_t y = 0; y < words.size(); y++) {
                        guesses.push_back(to_string(i) + to_string(j) + to_string(x) + words[y]);
                    }
                }
            }
        }
    }

    void crack(string pass, vector<string> &salts, vector<string> &guesses) {
        for(size_t i = 0; i < salts.size(); i++) {
            for(size_t j = 0; j < guesses.size(); j++) {
                string ep = crypt(guesses[j].c_str(), salts[i].c_str());

                if(ep.compare(salts[i] + pass) == 0) {
                    cout << "Password: " + guesses[j] << endl;
                }
            }
        }

        cout << "Password not found" << endl;
    }

    void broadcast_receive(vector<string> &encPass, vector<string> &words, vector<string> &salts,
                           vector<string> &guesses, int numProcesses, int procNum) {

        int buffer[4];

        buffer[0] = encPass.size();
        buffer[1] = words.size();
        buffer[2] = salts.size();

        MPI_Bcast(buffer, 3, MPI_INT, 0, MPI_COMM_WORLD);

        encPass.resize(buffer[0]);
        words.resize(buffer[1]);
        salts.resize(buffer[2]);

        vector<char> ep = convert(encPass);
        vector<char> w = convert(words);
        vector<char> s = convert(salts);
        vector<char> g = convert(guesses);

        MPI_Bcast(ep.data(), ep.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
        MPI_Bcast(w.data(), w.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
        MPI_Bcast(s.data(), s.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
        MPI_Bcast(g.data(), g.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
    }

    vector<char> convert(vector<string> &strings) {
        vector<char> cstrings;
        cstrings.reserve(strings.size());

        for(string s : strings) {
            for(size_t i = 0; i < strlen(s.c_str()); i++) {
                cstrings.push_back(s.c_str()[i]);
            }
        }

        return cstrings;
    }

当我注释掉file_IO(argc, argv, encPass, words, salts);程序编译时没有警告或错误但我不确定为什么这个函数会导致问题,因为它在我添加 Open MPI 代码之前编译得很好。

标签: c++openmpi

解决方案


推荐阅读