java实现账户管理器

在互联网高速发展的今天,想要浏览各种各样的网页,或者使用各种各样的应用,都需要注册账号,为了安全起见,不同的账号往往设置不同的密码,大量的密码很难完全记住,如果每次都靠"找回密码",那上网效率也太低了。。。

算了编不下去了,总之由于偶然想起学Python时写过一个类似的脚本,想尝试通过java实现,并进一步完善其功能,功能介绍及代码如下:

功能介绍

账户管理器可以保存任意账号和密码,和与之对应的 “键” ,例如我的steam账号就可以保存为

键:steam
账号:abc
密码:123

键的作用就是在大量账号密码对中,找到需要的那一对

这里提供了以下指令:

li/export                           列出所有保存的用户名和密码对 / 导出账户信息到当前目录
pw/un/uap/del 键            通过键得到密码 / 账号 / 账号和密码 / 删除对应账号和密码
add 键 账号 密码            添加新的账户信息
add excel文件路径         通过excel文件添加新的账户信息

注:这里的pw时passWord的缩写,un是userName的缩写,uap是userNameAndPassword的缩写,excel表格要求有三列,分别为key、username、password

这里保存信息是通过将Map对象保存成一个account文件,后续使用时通过读写该文件实现

main方法

public static void main(String[] args) {
    try{
        //用于保存账户信息的文件名
        File accountFile=new File("account");
        Map<String, User> account;
        if (!accountFile.exists()){
            //第一次使用,创建一个空对象保存到这个文件
            account=new HashMap<>();
            ObjectOutputStream outputStream =new ObjectOutputStream(new FileOutputStream(accountFile));
            outputStream.writeObject(account);
            outputStream.close();
        }else {
            //文件已存在,不是第一次使用,直接读取
            ObjectInputStream inputStream =new ObjectInputStream(new FileInputStream(accountFile));
            account = (HashMap)inputStream.readObject();
            inputStream.close();
        }
        //判断用户输入指令部分
        if (args.length==2 && "pw".equals(args[0])){
            //获取密码并拷贝到剪贴板
            getPassWord(account,args[1]);
        }
        else if (args.length==2 && "un".equals(args[0])) {
            //获取用户名并拷贝到剪贴板
            getUserName(account,args[1]);
        }
        else if (args.length==2 && "uap".equals(args[0])) {
            //获取用户名和密码信息
            getUserNameAndPassWord(account,args[1]);
        }
        else if (args.length==1 && "li".equals(args[0])) {
            //列出所有保存的用户名和密码信息
            listUserNameAndPassWord(account);
        }
        else if (args.length==4 && "add".equals(args[0])) {
            //添加用户名和密码信息
            addUserNameAndPassWord(account,accountFile,args);
        }
        else if (args.length==2 && "add".equals(args[0])){
            //根据excel文件添加用户名和密码信息
            addUserNameAndPassWordByFile(account,accountFile,args);
        }
        else if ((args.length==2 ||args.length==1) && "export".equals(args[0])){
            //根据给定路径导出用户信息到excel文件
            exportUserNameAndPassWordToFile(account,args);
        }
        else if (args.length==2 && "del".equals(args[0])) {
            //删除用户名和密码信息
            delUserNameAndPassWord(account,args[1]);
        }
        else {
            System.out.println("语法错误,正确语法为:");
            System.out.println("li/export");
            System.out.println("export 路径");
            System.out.println("pw/un/uap/del 键");
            System.out.println("add 键 用户名 密码");
            System.out.println("add .xlsx文件路径");
        }
        System.out.println("account文件所在位置:"+accountFile.getAbsolutePath());
    }
    catch (Exception e)
    {
        System.out.println("出现异常:"+ e.getMessage());
        System.out.println("可能的原因是:");
        System.out.println("1、保存账户信息的文件损坏,请删除重试");
        System.out.println("2、指定的路径错误");
    }
}
public static void getPassWord(Map account, String key){
    //得到剪贴板
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(new StringSelection(((User)account.get(key)).getPassWord()),null);
    System.out.println("已复制到剪贴板");
}
public static void getUserName(Map account, String key){
    //得到剪贴板
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(new StringSelection(((User)account.get(key)).getUserName()),null);
    System.out.println("已复制到剪贴板");
}
public static void getUserNameAndPassWord(Map account, String key){
    System.out.println("userName: "+((User)account.get(key)).getUserName());
    System.out.println("passWord: "+((User)account.get(key)).getPassWord());
    System.out.println("请手动复制");
}
public static void listUserNameAndPassWord(Map account){
    Set<String > keys = account.keySet();
    for (String key :keys){
        System.out.println(key+":"+((User)account.get(key)).getUserName()+":"+((User)account.get(key)).getPassWord());
    }
}
public static void addUserNameAndPassWord(Map account, File accountFile, String args[]) throws IOException {
    if (account.containsKey(args[1])){
        System.out.println("指定的键(key)已存在");
        return;
    }
    User user=new User(args[2],args[3]);
    account.put(args[1],user);
    ObjectOutputStream outputStream =new ObjectOutputStream(new FileOutputStream(accountFile));
    outputStream.writeObject(account);
    outputStream.close();
}
/**
 * 通过excel表格导入用户账户信息
 * @param account
 * @param accountFile
 * @param args
 * @throws IOException
 * @throws InvalidFormatException
 */
public static void addUserNameAndPassWordByFile(Map account, File accountFile, String args[]) throws IOException, InvalidFormatException {
    if(args[1].endsWith("xlsx")){
        XSSFWorkbook excelFile=new XSSFWorkbook(new File(args[1]));
        XSSFSheet firstSheet = excelFile.getSheetAt(0);
        //保存数据的第一行和最后一行
        int firstRowNum = firstSheet.getFirstRowNum();
        int lastRowNum = firstSheet.getLastRowNum();
        XSSFRow firstRow = firstSheet.getRow(firstRowNum);
        //保存数据的第一列和最后一列
        short firstCellNum = firstRow.getFirstCellNum();
        short lastCellNum = firstRow.getLastCellNum();
        int keyColNum=-1;
        int userNameColNum=-1;
        int passWordColNum=-1;
        for (int i= firstCellNum;i<lastCellNum;i++){
            if ("key".equals(firstRow.getCell(i).getStringCellValue().trim().toLowerCase())){
                keyColNum=i;
            }else if("username".equals(firstRow.getCell(i).getStringCellValue().trim().toLowerCase())){
                userNameColNum=i;
            }else if("password".equals(firstRow.getCell(i).getStringCellValue().trim().toLowerCase())){
                passWordColNum=i;
            }
        }
        if (keyColNum == -1||userNameColNum==-1||passWordColNum==-1){
            System.out.println("读取失败,格式错误");
            return;
        }
        for (int i=firstRowNum+1;i<=lastRowNum;i++){
            XSSFRow currentRow = firstSheet.getRow(i);
            currentRow.getCell(keyColNum).setCellType(CellType.STRING);
            currentRow.getCell(userNameColNum).setCellType(CellType.STRING);
            currentRow.getCell(passWordColNum).setCellType(CellType.STRING);
            User user=new User(currentRow.getCell(userNameColNum).getStringCellValue(),currentRow.getCell(passWordColNum).getStringCellValue());
            account.put(currentRow.getCell(keyColNum).getStringCellValue(),user);
        }
        excelFile.close();
        ObjectOutputStream outputStream =new ObjectOutputStream(new FileOutputStream(accountFile));
        outputStream.writeObject(account);
        outputStream.close();
    }
    else {
        System.out.println("文件格式不支持");
    }
}
/**
 * 将账户信息导出到excel表格
 * @param account
 * @param args
 */
public static void exportUserNameAndPassWordToFile(Map account,String args[]) throws IOException {
    XSSFWorkbook excel = new XSSFWorkbook();
    XSSFSheet sheet = excel.createSheet();
    XSSFRow firstRow = sheet.createRow(0);
    firstRow.createCell(0).setCellValue("key");
    firstRow.createCell(1).setCellValue("userName");
    firstRow.createCell(2).setCellValue("passWord");
    int curIndex =1;
    for (Object key:account.keySet()){
        XSSFRow curRow = sheet.createRow(curIndex++);
        curRow.createCell(0).setCellValue((String) key);
        curRow.createCell(1).setCellValue(((User)account.get(key)).getUserName());
        curRow.createCell(2).setCellValue(((User)account.get(key)).getPassWord());
    }
    String xlsxFilePath = ".\\account.xlsx";
    if (args.length==2){
        xlsxFilePath=args[1] + File.separator+ "account.xlsx";
    }
    OutputStream outputStream = new FileOutputStream(new File(xlsxFilePath));
    excel.write(outputStream);
    outputStream.close();
    excel.close();
}
public static void delUserNameAndPassWord(Map account, String key){
    if (!account.containsKey(key))
    {
        System.out.println("指定的键(key)不存在");
    }
    account.remove(key);
}

User类

这里还创建了一个User类,有两个String类型的属性userName和passWord,创建了对应的getter和setter、无参和有参构造、重写了toString、equals、hashCode方法(好像用不上?),这里也把代码附上

public class User implements Serializable {

    private static final long serialVersionUID = -7690676590515933732L;
    String userName;
    String passWord;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public User() {
    }

    public User(String userName, String passWord) {
        this.userName = userName;
        this.passWord = passWord;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(userName, user.userName) && Objects.equals(passWord, user.passWord);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userName, passWord);
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", passWord='" + passWord + '\'' +
                '}';
    }
}

批处理程序

直接 java -jar 用起来就太麻烦了,还必须和jar包在同一个目录下,这里可以利用批处理程序加环境变量的方法,在任何地方都能快速使用,这里以 java -jar jar包名 pw 键 为例,同时也是由于这个最常用

新建 pw.bat,输入以下内容:

@java -jar D:\path\accountManager.jar pw %*
@pause

注意:这里的路径只用于演示,不要完全拷贝,改成对应jar包所在路径

然后把当前bat文件所在路径加入环境变量中的Path中

以上步骤完成后,就能在任意位置打开控制台,或者直接 win + R 输入 pw 键 将对应的密码复制到剪贴板,相比于输入完整的java -jar...方便很多

这里的pw代表的是pw这个批处理文件,如果想使用 password 键 的方式,将批处理文件名改为password.bat即可

如果想增加其他快捷指令,例如un,只需额外创建一个un.bat,把上面代码中的pw改成un即可

account文件位置问题

如果在jar包所在路径使用控制台输入了完整的java -jar ...,生成的account文件就在jar包所在目录,如果使用win+R的方式,生成的account文件是在 C:\Users\用户名 目录下,这是因为try内第一句代码在执行时受工作路径影响。

如果想让account文件在一个固定的位置,把第一行代码改为绝对路径就行了。

最后

先提供一下打包好的jar包,由于批处理文件中的路径不固定,这里就不提供了

链接:https://pan.baidu.com/s/1fjqnFlYvXGGZW1cqRbWJBA 
提取码:pw86

项目的依赖:后两个是由于在使用的时候总是提示ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console…才加上的

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.23.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.23.1</version>
    </dependency>
</dependencies>

以及,这里并不讨论安全性的问题,如果密码保存在电子设备上,还是建议多备份。

24/12/2 更新,增加了读取excel表格和导出到excel表格

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值