Java 家庭作业:清除散列?

Java 家庭作业:清除散列?,java,Java,我在netbeanside8.1中使用Java8+ 这是家庭作业的一部分,但这次我最想找的是答案 我基本上只限于JDK,不允许使用以下代码: 正则表达式 缓冲读取器 溪流 尝试/抓住 列表 基本上,我的选项仅限于变量、基本字符串方法(indexOf()、contain()等)、for/while循环、if/then或if/else、FileInputStream、Scanner和其他非常基本的代码。甚至使用我的分隔符将文件读入数组也可能有问题 我有一个简单的身份验证系统的代码。在一个文本文件

我在netbeanside8.1中使用Java8+

这是家庭作业的一部分,但这次我最想找的是答案

我基本上只限于JDK,不允许使用以下代码:

  • 正则表达式
  • 缓冲读取器
  • 溪流
  • 尝试/抓住
  • 列表
基本上,我的选项仅限于变量、基本字符串方法(indexOf()、contain()等)、for/while循环、if/then或if/else、FileInputStream、Scanner和其他非常基本的代码。甚至使用我的分隔符将文件读入数组也可能有问题

我有一个简单的身份验证系统的代码。在一个文本文件中,我有6个“用户”,包括用户名、摘要、纯文本密码和他们的帐户角色。我已经将文本文件拉入二维数组,并使用该数组进行比较。用户收到一个对话框输入用户名,然后另一个对话框输入密码。while循环比较用户名和密码,然后报告
登录正确。
登录错误。
问题是,它对第一个用户非常有效,或者输入了错误的信息。对于用户2-6,它陷入了“输入用户名和密码”的无限循环中。以下是相关代码。另外,提前感谢您的帮助

文件:credentials.txt:分隔符是\t(制表符)和\r(回车符)

对于主类:

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; 
    }

}
import java.io.IOException;
公共类测试认证系统{
公共静态void main(字符串[]args)引发IOException,异常{
TestSystemLogin sysLogin=新建TestSystemLogin();//SystemLogin的对象
int loginCounter=0;//跟踪登录尝试。
final int LOGIN_MAX=3;//最大登录尝试次数。
//让用户尝试登录。

while(loginCounter只有当错误登录尝试>=3时,while循环才会结束,否则,此无限循环将始终发生。此外,读取文件中的所有条目后,您需要另一个条件来终止循环


建议您在每次迭代中读取文件,填充数组,关闭文件,继续整个过程,再次读取文件,填充数组,并继续执行应该以只读取一次文件的方式更改的操作,填充二维数组并进行比较。

运行代码时,我在读取凭证时遇到问题als.txt。要验证您的代码是否在计算机上正确读取了credentials.txt,请通过将读取循环替换为

    // Create array of credentials.txt
    for (i = 0; i < NUM_ROWS_CRED; ++i) {
        for (j = 0; j < NUM_COLS_CRED; ++j) {
            String s = inFS.next();
            System.out.print(s+" ");
            credArray[i][j] = s;
        }
        System.out.println();
    }

不要使用并行数组,创建一个类来保存每个用户的信息。另外,您不应该将明文密码存储在任何地方,这是一个安全问题,比较MD5哈希就是您所需要的。您也不需要“清除哈希”每次创建一个新的MD5实例时。跟踪IDE调试器中的代码以找出问题所在。@JimGarrison是的,我完全同意您关于存储纯文本密码的安全风险的看法。在实时环境中,我永远不会这样做。对于此任务,它是按“原样”分配给我们的我们无法调整它。哦,不!其他人对@JimGarrison的建议做了一个很好的解释,然后把它拿走了。看起来你需要做一些调试。断点、断言语句和使用
System.out.println
调试将是你的朋友。堆栈溢出问题需要有一个明确的答案。“这在不创建单独类的情况下是可能的吗?"-您已经有两个类了,是否有禁止创建其他类的家庭作业规则?如果您仅限于两个文件,则可以在
TestSystemLogin
类中创建一个包含名称、哈希、密码和角色成员的类。如果登录成功,则在显示对话框后,它也应
中断;
。它可以成功用于我的第一行用户。至于你的建议,你能提供一点示例代码,关于我如何称呼多个用户吗?另外,为了澄清一点,我的
credentials.txt
文件有6行4列,每行由
\t
(制表符)分隔,第四列以
\r
结尾(回车符)。我可以看到如何创建一个类来处理一个用户,在本例中是
credArray[0][j]
,但是我将如何使用它来处理其他行?感谢您的帮助。我编辑了我的原始问题以提供清晰性,并简化了代码以简洁性。如果您能再次查看,我将不胜感激。
    // Create array of credentials.txt
    for (i = 0; i < NUM_ROWS_CRED; ++i) {
        for (j = 0; j < NUM_COLS_CRED; ++j) {
            String s = inFS.next();
            System.out.print(s+" ");
            credArray[i][j] = s;
        }
        System.out.println();
    }
    // Use carriage return and tab as token separators
    inFS.useDelimiter("[\\r\\n\\t]");