如果字符串长度大于给定参数if语句,则else节不激活

时间:2019-09-11 22:22:20

标签: c encryption fgets

具有输入验证功能的基本加密,如果输入在定义的参数之内且需要用户输入进入每个阶段,则程序会根据需要运行;如果输入大于定义的参数,则应触发说密码无效,而是运行整个程序无需用户输入即可触发前进。

import CallRow from "./CallRow";
import React from "react";

class SearchPage extends React.Component {
  constructor() {
    super();
    this.state = {
      search: "Level Up"
    };
  }

  updateSearch(event) {
    this.setState({ search: event.target.value.substr(0, 20) });
  }

  render() {
    return (
      <div>
        <ul>
          {this.props.calls.map(call => (
            <CallRow call={call} key={call.id} />
          ))}
        </ul>
        <input
          type="text"
          value={this.state.search}
          onChange={this.updateSearch.bind(this)}
        />
      </div>
    );
  }
}

export default SearchPage;

1 个答案:

答案 0 :(得分:3)

我试图破译代码的目的是什么,我已经读了茶道,得出的结论(也许是错误的)是,问题的症结在于输入和分支控制。加密本身。

“孔子”注释只是半心半意的建议,因为“缓冲区大小永不跳过” 成为您提示用户选择哪个分支的关键指示。为什么?

  • 如果与原始代码一样,您的缓冲区大小为20,并告诉fgets最多读取10个字符,那么如果用户输入的内容多于{ {1}}个字符,其余字符留在10 未读 中。
  • stdin中未读的任何字符将很高兴地用作以后的每个stdin语句的输入,从而使您无法完全控制代码的分支方式。
  • 使用足够大小的缓冲区并允许getchar()一次使用一整行,将确保fgets(输入缓冲区)中没有剩余未读的字符。您会发现这是在C中接受大多数用户输入的关键。

因此,确保有足够大小的缓冲区并每次使用一行输入,对于控制代码的下一个位置至关重要。

提供一个能够保存每一行输入的缓冲区的替代方法是读取所需的字符数,然后在下一次输入之前手动清空stdin。这可以像读取字符一样简单,直到达到stdin'\n'为止。但是有一个问题。您必须知道字符,然后再尝试使用您使用的任何功能清空EOF(例如stdin会阻塞-等待输入,直到出现输入为止)。如果您在没有什么可清空的情况下尝试以此方式清空getchar(),则您的用户将盯着闪烁的光标,想知道该怎么做。

返回您的代码。逻辑有点难以理解,但是从包含的注释中可以看出,您出于加密目的考虑使用了正确的密码短语,即一个带有stdin字符的短语。空密码短语或包含6个或更多字符的密码短语被视为无效。 (从传递阶段的角度来看实际的数量没有关系-这是关于输入和分支控制的练习)

如果我了解1-5字符(加密)或1-50或更多(无效)逻辑,那么您将需要调整代码结构以遵循靠近一点。从概述的角度来看,您要么有一个很好的密码短语来加密,要么没有。那将控制代码中的主要分支。您可以在单个6语句中提供逻辑,例如

if {..} else {..}

将上面的示例与您的示例中具有的多个独立语句组进行对比,这应该说明为什么您在代码中的决策树方面遇到了麻烦。

现在您的提示提示用户按 Enter 。当您尝试使用单个 /* if input is longer than 0 but shorter than 6, encrypt data */ if (length && length < 6) { /* all your good pass phrase code goes here */ } else { /* invalid pass phrase to begin with */ fputs ("error: pass phrase empty or greater than 5 chars.\n", stderr); return 1; } 捕获输入内容时,如果getchar()中存在任何字符,则它非常脆弱并且容易被跳过,并且存在将stdin中的字符保留为未读的相同问题。如果超过了 Enter 。在这里,只需声明另一个字符数组以用于临时输入,其大小与stdin数组相同。现在,不用input[],只需再次使用getchar(),甚至可以单独捕获 Enter

(它有足够的能力,因为它读取fgets()并将其包含在填充的缓冲区中,因此不会像'\n'那样阻塞等待输入的时间)

担心在两个缓冲区中使用512字节的大小-不用。大多数操作系统至少提供1兆的堆栈空间,因此512字节仅代表您可用堆栈存储的getchar()。 (您仍然有0.048%个字节的堆栈空间可用)

进行此更改后,您的代码可以被重写为包含与在第一个1048576 - 512 = 1048064块内处理良好/加密密码有关的所有逻辑,例如

if {...}

注意:)位于#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXC 256 /* if you need a constant, #define one (or more) */ int main (void) { char input[MAXC], /* buffer to hold pass phrase */ tmp[MAXC]; /* temporary buffer for [enter] input */ size_t i, /* declares an UNINTIALIZED size_t */ length; /* (ditto) */ fputs ("Your pass phrase is: ", stdout); /* no conversion, fputs is fine */ if (!fgets (input, MAXC, stdin)) { fputs ("(user canceled input)\n", stderr); return 1; } /* remove '\n' by overwriting with '\0' (if present) * saving length of input in length */ input[(length = strcspn(input, "\n"))] = 0; /* if input is longer than 0 but shorter than 6, encrypt data */ if (length && length < 6) { int encrypted = 0; /* flag keeping state of if pw encrypted */ for (i = 0; i < length; i++) /* encrypt the pass phrase */ input[i] ^= 0x7f; encrypted = 1; /* set flag true */ /* print encrypted text in an hex format (change as desired) */ fputs ("\nTo see the encrypted text press [enter]: ", stdout); if (fgets (tmp, MAXC, stdin) && *tmp == '\n') { for (i = 0; i < length; i++) printf (" %02x", input[i]); putchar ('\n'); } /* decrypt restoring plain-text pass phrase */ fputs ("\ndecrypted pass phrase, press [enter]: ", stdout); if (fgets (tmp, MAXC, stdin) && *tmp == '\n') { for (i = 0; i < length; i++) input[i] ^= 0x7f; encrypted = 0; /* set flag false after decryption */ } else { /* if user pressed any other key (or generated EOF) */ fputs ("error: user chose not to decrypt pass phrase.\n", stderr); return 1; } /* output decrypted plain-text pass pharase (if decrypted) */ fputs ("\nTo see recovered text press [enter]: ", stdout); if (fgets (tmp, MAXC, stdin) && *tmp == '\n' && !encrypted) { for (i = 0; i < length; i++) putchar (input[i]); putchar ('\n'); } } else { /* invalid pass phrase to begin with */ fputs ("error: pass phrase empty or greater than 5 chars.\n", stderr); return 1; } return 0; } 标志上方,仅用于保持encrypted的内容当前是否被加密的状态,以便在此之前提供附加的条件检查。您尝试打印解密的密码短语

使用/输出示例

有效的密码:

input[]

用户选择不解密大小写:

$ ./bin/pass0-5
Your pass phrase is: abcde

To see the encrypted text press [enter]:
 1e 1d 1c 1b 1a

decrypted pass phrase, press [enter]:

To see recovered text press [enter]:
abcde

密码短语太长的情况:

$ ./bin/pass0-5
Your pass phrase is: abcde

To see the encrypted text press [enter]:
 1e 1d 1c 1b 1a

decrypted pass phrase, press [enter]: No, I don't want to!
error: user chose not to decrypt pass phrase.

密码为空的情况:

$ ./bin/pass0-5
Your pass phrase is: abcdef
error: pass phrase empty or greater than 5 chars.

我不知道我是否正确阅读了茶叶,但是从您的评论和原始问题来看,这似乎是您真正关注的领域。仔细研究一下,如果您还有其他问题,请告诉我,如果我对您的问题的要旨有误,请告诉我,我们很乐意为您提供进一步的帮助。