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个原因:
- 让我对wlan的连接有了初步的了解;
- 让我掌握了2个类:
java.lang.Process
、java.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
计算步骤:
- 求国庆星期的方法:无论平年或闰年,国庆的星期是此年对7取模(取余)。
- 断是平年还是闰年:
年份 * 5/4
。若取整为本身,则是闰年。 - 若是平年,元旦与国庆的星期相同;若是闰年,元旦的星期比国庆少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; }
使用类:Process、Runtime、BufferedReader、OutputStreamWriter。
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命令:
- 导出wlan配置文:
netsh wlan export profile name=ssid_name
; - 连接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(); } }
本文持续更新中。。。