【问题标题】:Linux - Memory Mapped FileLinux - 内存映射文件
【发布时间】:2014-01-21 21:11:12
【问题描述】:

我正在尝试使用 mmap 实现凯撒密码。我认为密码工作得很好,但问题是 mmap。它的想法是更新文件,如果有变化。 到目前为止,它不起作用。我可以读取内存映射文件并打印它。但是,如果我进行任何修改,就会出现分段错误。不幸的是,我自己无法解决问题。所以,如果你能帮助我,我将不胜感激。

这里是代码。

int main (int argc, char *argv[]) {

    if(argc != 5)
       fprintf(stdeer, "usage: ./cipher (encrypt|decrypt) <file name> (casar| vigenere) <key>\n");

    // (encrypt / decrypt) can be found in argv[1]
    // filename in argv[2]
    // encryption method in argv[3]
    // key in argv[4]
    int fd = open(argv[2], O_RDWR, S_IWRITE | S_IREAD);
    if (fd < 0)
        hanle_error("open");

    off_t len = lseek(fd, 0, SEEK_END);
    if (len == (off_t)-1)
        handle_error("lseek");

    unsigned char* data = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // Add PROT_WRITE
    if (data == MAP_FAILED)
        handle_error("mmap");

    char c = *argv[4];
    int key = 0;

    if(strcmp(argv[3], "caesar") == 0) {
        key = c - 48;
        if(strcmp(argv[1], "decrpyt") == 0)
            key = -key;
        int num = 0;
        for(int size_t i = 0; i < (size_t)len; i++) {
            if(data[i] >= 97 && data[i] <= 122) {
                num = data[i];
                num +=key;
                if(num > 'z') {
                    num -= 26;
                    data[i] = num + '0';
                } else if (num < 'a') {
                    num += 26;
                    data[i] = num + '0';
                } else {
                    data[i] = num + '0';
                }
            } else {
                continue;
            }
        }
    }

    return 0;
}

可能的输入可以是任何东西,例如

SsWd asdas
qwmkfd aw.

上面的算法应该只修改小写字母,其余部分保持原样。

我希望有人能帮助我。

另外,我只实现了凯撒密码。

编辑:添加 PROT_WRITE 后,段错误消失了。但是知道我对修改后的小写字母有奇怪的问号。有谁知道为什么?

【问题讨论】:

  • 你认为PROT_READ是什么意思?...
  • @OliCharlesworth:嗯,我一定忘记了。我不知道为什么,但谢谢。但还有一个问题。现在,我得到了修改后的小写字母奇怪的问号。你知道为什么吗?

标签: c linux segmentation-fault encryption memory-mapped-files


【解决方案1】:

如果你也想写入文件,那么

unsigned char* data = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0);

应该是

unsigned char* data = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

这可能不是唯一的问题,但可以解释段错误。

原因不言自明!

【讨论】:

  • 好吧,我不知道,我是怎么错过的。感谢您的提醒。但是知道我得到了修改后的小写字母奇怪的问号。你知道它可能导致什么吗?
  • 阅读您的代码,这将取决于 key 的值是什么,即 argv[4] 中的 i。如果您的代码不打算这样做,我猜您错误地实现了凯撒密码。我将使用小写字符和您写为“键”的任何值来处理代码,然后看看结果如何。然而,这不再是一个“内存映射文件”的问题——我认为这部分已经得到了正确的回答!
  • @user2965601 是的,我想这就是 abligh 试图沟通的内容。如果这解决了您的(映射)问题,请接受答案。
猜你喜欢
  • 2017-09-18
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 2016-02-23
  • 2014-03-04
相关资源
最近更新 更多