【发布时间】:2016-10-06 20:52:38
【问题描述】:
我在 NetBeans IDE 8.1 中使用 Java8+。
这是家庭作业的一部分,但这次我正在寻找答案。
我基本上只限于JDK,并且不允许使用以下代码:
- 正则表达式
- 缓冲阅读器
- 流
- 尝试/抓住
- 列表
基本上,我的选项仅限于变量、基本字符串方法(indexOf()、contain() 等)、for/while 循环、if/then 或 if/else、FileInputStream、Scanner 和其他非常基本的代码。即使使用我的分隔符将文件读入数组也可能有问题。
我有一些用于简单身份验证系统的代码。在一个文本文件中,我有 6 个“用户”,包括用户名、摘要、纯文本密码和他们的帐户角色。我已将文本文件拉入二维数组,并使用它进行比较。用户收到一个对话框输入用户名,然后另一个输入密码。 while 循环比较用户名和密码,然后报告Good login. 或Bad login. 问题是,它对第一个用户非常有效,或者如果输入了不正确的信息。对于用户 2-6,它陷入了“输入用户名和密码”的无限循环。下面是相关代码。另外,提前感谢您的帮助。
文件:credentials.txt: 分隔符是 \t(制表符)和 \r(回车)
griffin.keyes 108de81c31bf9c622f76876b74e9285f alphabet soup zookeeper
rosario.dawson 3e34baa4ee2ff767af8c120a496742b5 animal doctor admin
bernie.gorilla a584efafa8f9ea7fe5cf18442f32b07b secret password veterinarian
donald.monkey 17b1b7d8a706696ed220bc414f729ad3 M0nk3y business zookeeper
jerome.grizzlybear 3adea92111e6307f8f2aae4721e77900 grizzly1234 veterinarian
bruce.grizzlybear 0d107d09f5bbe40cade3de5c71e9e9b7 letmein admin
对于主类:
import java.io.IOException;
public class TestAuthenticationSystem {
public static void main(String[] args) throws IOException, Exception {
TestSystemLogin sysLogin = new TestSystemLogin(); // Object of SystemLogin
int loginCounter = 0; // Tracks login attempts.
final int LOGIN_MAX = 3; // Max login attempts.
// Have User attempt to login.
while (loginCounter <= (LOGIN_MAX - 1)) {
sysLogin.setCredArray();
sysLogin.setCredentials(); // Set credentials
if (sysLogin.matchUsername(sysLogin.getCredArray(), sysLogin.getUsername()) == true) {
if (sysLogin.passwordMatch(sysLogin.getCredArray(), sysLogin.getUsername())
== true) {
System.out.println("Good login.");
break;
}
else {
++loginCounter;
System.out.println("Bad login.");
}
}
}
}
}
还有二等:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
public class TestSystemLogin {
private FileInputStream fileByteStream = null; // File input stream
private Scanner inFS = null; // Scanner object
final private Scanner input;
private String username = ""; // Holds username
private String password = ""; // Holds password
private final String [][] credArray = new String[6][4]; // Array for credentials.txt
public TestSystemLogin() {
this.input = new Scanner(System.in);
}
public void setCredentials() {
System.out.println("Enter Username: ");
username = input.next().toLowerCase();
input.nextLine();
System.out.println("Enter Password: ");
password = input.nextLine();
}
// Return variable username.
public String getUsername() {
return username;
}
// Return variable password.
public String getPassword() {
return password;
}
public void setCredArray() throws IOException {
int i = 0; // Index variable
int j = 0; // Index variable
// Import credentials data.
fileByteStream = new FileInputStream("credentials.txt");
inFS = new Scanner(fileByteStream);
// Use carriage return and tab as token separators
inFS.useDelimiter("[\\r\\t]");
// Create array of credentials.txt
for (i = 0; i < 6; ++i) {
for (j = 0; j < 4; ++j) {
credArray[i][j] = inFS.next();
}
}
fileByteStream.close(); //Closes file.
}
public String[][] getCredArray() {
return credArray;
}
// Compare username to recorded username.
public boolean matchUsername(String[][] credArray, String userUsername) boolean isTrue = false;
int i = 0;
for (i = 0; i < credArray.length; ++i) {
if (credArray[i][0].equals(userUsername)) {
isTrue = true;
break;
}
}
return isTrue;
}
public boolean passwordMatch(String[][] credArray, String userUsername) {
boolean isTrue = false;
int i = 0;
for (i = 0; i < credArray.length; ++i) {
if (credArray[i][0].equals(userUsername)) {
if (credArray[i][2].equals(password)) {
isTrue = true;
break;
}
}
}
return isTrue;
}
}
预期结果: 我可以输入 6 个用户名中的任何一个及其相应的密码,并收到“登录良好”。
发生了什么: 对于用户 2-6,我陷入了询问用户名和密码的无限循环。
以前的答案建议不要使用二维数组,将每个用户信息放入一个类中。在不创建其他类的情况下这可能吗?如果是这样,请为每个用户提供该类的示例,以及调用它的相应代码。
【问题讨论】:
-
不要使用并行数组,创建一个类来保存每个用户的信息。此外,您不应该将明文密码存储在任何地方,这是一个安全问题,只需比较 MD5 哈希值即可。您也不需要在每次创建新的 MD5 实例时“清除哈希”。跟踪 IDE 调试器中的代码以查明问题所在。
-
@JimGarrison 是的,我完全同意你关于存储纯文本密码的安全风险的看法。在实时环境中,我永远不会这样做。对于这项任务,它是“按原样”分配给我们的,我们无法调整。
-
哦不!其他人发表的评论似乎很好地解释了@JimGarrison 的建议,然后将其删除。
-
看来你需要做一些调试。使用
System.out.println进行断点、断言语句和调试将成为您的朋友。堆栈溢出问题需要有一个minimal reproducible example。 -
“如果不创建单独的类,这可能吗?” - 你已经有两个类,是否有禁止创建其他类的作业规则?如果您仅限于两个文件,您可以在
TestSystemLogin类中创建一个inner class,该类具有名称、哈希、密码和角色成员。
标签: java