[Java]小功能
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/130858061
出自【进步*于辰的博客】
文章目录
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();
}
}
本文持续更新中。。。
[Java]小功能的更多相关文章
- Java小功能大杂烩
生成UUID: import java.util.UUID; public class ProductUUID { // 随机返回前十位的UUID public static String getUU ...
- Java实现点击一个Jlabel增加一个Jlabel的小功能
当界面生成以后,自己想做一个点击一个Jlabel增加一个Jlabel,即类似于QQ的添加好友以后可以及时的加进一个好友.自己做了好久,发现不能及时刷新.在网上查了一下,然后自己研究了一小会.发现需要v ...
- 网站开发---js与java实现的一些小功能
记录一下网站开发过程中的一些小功能 1.js获取当前年份: <span>Copyright © 2017-<script>document.write( new Date(). ...
- C#、Java中的一些小功能点总结(持续更新......)
前言:在项目中,有时候一些小的功能点,总是容易让人忽略,但是这些功能加在项目中往往十分的有用,因此笔者在这里总结项目中遇到的一些实用的小功能点,以备用,并持续更新...... 1.禁用DataGrid ...
- Servlet的5种方式实现表单提交(注册小功能),后台获取表单数据
用servlet实现一个注册的小功能 ,后台获取数据. 注册页面: 注册页面代码 : <!DOCTYPE html> <html> <head> <meta ...
- java正则表达式之java小爬虫
这个java小爬虫, 功能很简单,只有一个,抓取网上的邮箱.用到了javaI/O,正则表达式. public static void main(String[] args) throws IOExce ...
- Java小项目--坦克大战(version1.0)
Java小项目--坦克大战<TankWar1.0> 这个小项目主要是练习j2se的基础内容和面向对象的思想.项目实现了基本的简单功能,我方一辆坦克,用上下左右键控制移动方向,按F键为发射炮 ...
- Java学习笔记三十:Java小项目之租车系统
Java小项目之租车系统 一:项目背景介绍: 根据所学知识,编写一个控制台版的“呱呱租车系统” 功能: 1.展示所有可租车辆: 2.选择车型.租车量: 3.展示租车清单,包含:总金额.总载货量以及其车 ...
- Servlet的5种方式实现表单提交(注册小功能)
Servlet的5种方式实现表单提交(注册小功能),后台获取表单数据 用servlet实现一个注册的小功能 ,后台获取数据. 注册页面: 注册页面代码 : <!DOCTYPE html> ...
- Java小对象的解决之道——对象池(Object Pool)的设计与应用
一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...
随机推荐
- 致敬英雄,共悼逝者,css 让页面变黑白
壹 ❀ 引 今天是四月四日清明节,也是全国哀悼抗疫烈士的一天.细心的同学可以发现,不仅是娱乐活动以及游戏全部停止,当我们打开各大门户网站,网站页面也都变成了黑白,那么具体怎么做呢,这里可以借用CSS3 ...
- Java并发编程实例--15.在同步代码块中使用条件
并发编程中有个经典问题: 生产消费者问题. 我们有一个数据缓冲区,一个或多个生产者往其中存入对象,另外一个或多个消费者从中取走. 因此,该数据缓冲区是一个共享数据结构,我们需要对其添加读取同步机制,但 ...
- golang 打隧道和端口转发
`package main import ( "golang.org/x/crypto/ssh" "io" "log" "net& ...
- Notepad++设置删除当前行快捷键
Notepad++默认能实现"删除当前行"效果的快捷键是Ctrl + L,实际上这不并是真正意义上的删除当前行,而是剪切当前行. 而Eclipse中实现删除当前行的快捷键是:Ctr ...
- go语言中的数据类型
数据类型可分为四类 基础类型 数字.字符串和布尔型 复合类型 数组.结构体 引用类型 指针.切片.map.函数.通道channel 接口类型 interface
- 无法加载 DLL“librdkafka”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
我这个错误是在引用了封装kafka项目的情况下提示的. 解决方案:在本项目里面安装 RdKafka ,再次运行就好了.
- CUDA、CUDNN 安装
安装 CUDA.CUDNN 1. CUDA CUDA 是 NVIDIA 发明的一种并行计算平台和编程模型.它通过利用图形处理器 (GPU) 的处理能力,可大幅提升计算性能. 官方地址 https:// ...
- 【Azure 应用服务】在Azure App Service for Windows 中部署Java/NodeJS/Python项目时,web.config的配置模板内容
问题描述 在Azure App Service for Windows 中部署web项目时候,需要在wwwroot下设置web.config,对于不同语言的项目,web.config文件中的httpP ...
- 【Azure Redis 缓存】Azure Cache for Redis 是否记录具体读/写(Get/Set)或删除(Del)了哪些key呢?
问题描述 在Azure Redis的门户活动日志中,可以查看到的是对于Redis资源本身的操作.但是对于客户端连接到Redis服务后,对服务所做出的读写,或删除操作,是否有日志可以查看到呢? 问题回答 ...
- Nebula Graph|如何打造多版本文档中心
本文首发于 Nebula Graph Community 公众号 世界上没有完美的产品,每个不完美的产品都需要一份文档. 为什么需要文档 打造出一款产品后,我们需要一份文档来回答以下问题: 设计这款产 ...