The Extra Story of Cryptography on the Growth of Programmers ----- String (ascii) to Binary

Recently, I have been introducing the relevant knowledge of cryptography, but the theoretical knowledge is always boring and requires some practical combat. For this reason, after studying the DES algorithm, I found that I can start to develop from here—that is, the character Serial to binary.

1. The method of converting ordinary base (8, 10, 16) base to binary

This is also relatively simple. The conversion from octal to binary can be divided bit by bit according to the octal, and each bit is replaced with a three-digit binary number (because 2^3=8), and the hexadecimal is four.
For convenience, we first set up an enumeration type, which is called EncodeRadix, as shown in the figure below, and we will talk about it later when it is useful:

/**
	 * 枚举类型
	 * @author zygswo
	 *
	 */
	public enum EncodeRadix{
    
    
		DEC(10,null),
		OCT(8,3),
		HEX(16,4),
		BINARY(2,1);
		private int value = 2;
		private Integer length = 1;
		private EncodeRadix(int value, Integer length) {
    
    
			this.value = value;
			this.length = length;
		}
		public int getValue() {
    
    
			return value;
		}
		public void setValue(int value) {
    
    
			this.value = value;
		}
		public Integer getLength() {
    
    
			return length;
		}
		public void setLength(Integer length) {
    
    
			this.length = length;
		}
	}

To explain, the first parameter is the base value of the bit, and the second is the number of bits required to convert to binary.

The following is to create a base number table, taking hexadecimal as an example, why create a base table here? Everyone knows that array query is O(1) level, so the query speed will be very fast, and the value corresponding to each character can be obtained, such as "1" corresponds to 1, "2" corresponds to 2, "A" corresponds to 10, etc. .

private static char[] HEX_TABLE = {
    
    '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

The next step is the conversion code, and the conversion is also very simple, as long as each digit is matched with the data in the base number table one by one, and then the value of each digit is obtained, and then converted into binary. Of course, before conversion, we need to check whether the current string matches the base value corresponding to the input enumeration type, the code is as follows:

	/**
	 * 判断是否属于该进制
	 * @param text 要转的文本
	 * @param radix 原进制
	 * @return
	 */
	private static boolean verifyRadix(String text, EncodeRadix radix) {
    
    
		int value = radix.getValue();
		String str = new String(HEX_TABLE);
		for(char ch : text.toCharArray()) {
    
    
			int index = str.indexOf(ch);
			if (index <0 || index >= value) {
    
    
				return false;
			}
		}
		return true;
	}

This reflects the benefits of the enumeration type. We obtain the first parameter value of the enumeration type, which is the corresponding base value of the enumeration type, and then judge whether the text text conforms to the rules (loop through each digit) number). The purpose of converting the base to the String type here is to obtain the base value corresponding to the character on each bit faster. (Use indexOf to obtain, that is to say, the subscript is the base value)

Next, we can perform hexadecimal conversion, the code is as follows:

/**
	 * 转2进制(10进制、16进制和8进制转成二进制)
	 * @param text 要转的文本
	 * @param radix 原进制
	 * @return
	 */
	public static String toBinary(String text, EncodeRadix radix) {
    
    
		//判断是否符合进制规则
		if (!verifyRadix(text, radix)) {
    
    
			throw new RuntimeException("进制有误");
		}
		//将进制数表转换成String类型,好处是可以更快的获取每个位的该进制数值
		String str = new String(HEX_TABLE);
		StringBuilder result = new StringBuilder("");
		//10转2进制
		if (radix.getValue() == 10) {
    
    
			long l = Long.valueOf(text);
			while(l > 0) {
    
    
				result.append(l % 2);
				l = l >> 1;
			}
			result = result.reverse();
		} else {
    
    
			//16、8转2进制
			//取每一位上的数字
			for(char ch : text.toCharArray()) {
    
    
				int index = str.indexOf(ch);
				int res = index, pre = index;
				String res1 = "";
				//keypoint1:关键点一
				while(res > 0) {
    
    
					res = res >> 1 << 1;
					res1 = ((pre ^ res) == 0 ? "0" : "1") + res1; //异或判断当前位上数字是否为1
					res = res >> 1;
					pre = pre >> 1;
				}
				//keypoint1:关键点二
				//扩充n位
				while (radix.getLength()!= null && 
						res1.length() < radix.getLength()) {
    
    
					res1 = "0" + res1;
				}
				result.append(res1);
			}
		}
		return result.toString();
	}

Key point 1: Bit operations are used.
This will undoubtedly increase the cost of understanding, but it can reduce the time-consuming cost of operations. So how to understand these lines of code?
For example: the input is 10, that is (1010) 2,
first of all , res means the value of the first few digits after replacing the number at the end with 0 each time , that is, (1010) in the first round 2, the second round is (0100)2 [logic shift one bit to the right, and the end is changed to 0]
and pre represents the original data, and the end is not replaced with 0 , that is, in the first round it is (1010)2, and in the second round it is (0101) 2 [Logical right shift one bit, and then change the end to 0]
You should be able to guess the follow-up when you see this, that is, use res and pre to perform XOR operation. If it is 0, it means that the last number is 0, which is 1 means that the last number is 1, so that the value of the rightmost bit (last bit) after each loop can be obtained. After that, it is enough to logically shift the pre and res to the right each time until res is 0.

Key point 2: Extended operation
Bit expansion is to make up for the lack of digits, and pay attention to filling in first.

Finally, the binary string can be obtained through the tostring of the stringbuilder, and there is no limit to the number of digits.

2. String to binary method

Here we first put the code:

/**
	 * 转2进制(字符串转成二进制)
	 * @param text 要转的文本
	 * @return
	 */
	public static String strtoBinary(String text) {
    
    
		StringBuilder result = new StringBuilder("");
		//取每一位上的数字
		for(char ch : text.toCharArray()) {
    
    
			int res = ch, pre = ch;
			String res1 = "";
			while(res > 0) {
    
    
				res = res >> 1 << 1;
				res1 = ((pre ^ res) == 0 ? "0" : "1") + res1; //异或判断当前位上数字是否为1
				res = res >> 1;
				pre = pre >> 1;
			}
			//扩充至8位
			while (res1.length() < 8) {
    
    
				res1 = "0" + res1;
			}
			result.append(res1);
		}
		return result.toString();
	}

Let’s talk about the changed part, one is that the value of the obtained string has no base, and the other is to directly convert the string into ascii code and then perform the operation.

The overall code is as follows:

package common;
/**
 * 进制转换类
 * @author zygswo
 *
 */
public class EncodeUtil {
    
    
	private static char[] HEX_TABLE = {
    
    '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
	
	/**
	 * 枚举类型
	 * @author zygswo
	 *
	 */
	public enum EncodeRadix{
    
    
		DEC(10,null),
		OCT(8,3),
		HEX(16,4),
		BINARY(2,1);
		private int value = 2;
		private Integer length = 1;
		private EncodeRadix(int value, Integer length) {
    
    
			this.value = value;
			this.length = length;
		}
		public int getValue() {
    
    
			return value;
		}
		public void setValue(int value) {
    
    
			this.value = value;
		}
		public Integer getLength() {
    
    
			return length;
		}
		public void setLength(Integer length) {
    
    
			this.length = length;
		}
	}
	
	/**
	 * 转2进制(10进制、16进制和8进制转成二进制)
	 * @param text 要转的文本
	 * @param radix 原进制
	 * @return
	 */
	public static String toBinary(String text, EncodeRadix radix) {
    
    
		if (!verifyRadix(text, radix)) {
    
    
			throw new RuntimeException("进制有误");
		}
		String str = new String(HEX_TABLE);
		StringBuilder result = new StringBuilder("");
		System.out.println(text);
		//10转2进制
		if (radix.getValue() == 10) {
    
    
			long l = Long.valueOf(text);
			while(l > 0) {
    
    
				result.append(l % 2);
				l = l >> 1;
			}
			result = result.reverse();
		} else {
    
    
			//16、8转2进制
			//取每一位上的数字
			for(char ch : text.toCharArray()) {
    
    
				int index = str.indexOf(ch);
				int res = index, pre = index;
				String res1 = "";
				while(res > 0) {
    
    
					res = res >> 1 << 1;
					res1 = ((pre ^ res) == 0 ? "0" : "1") + res1; //异或判断当前位上数字是否为1
					res = res >> 1;
					pre = pre >> 1;
				}
				//扩充n位
				while (radix.getLength()!= null && 
						res1.length() < radix.getLength()) {
    
    
					res1 = "0" + res1;
				}
				System.out.println("res1 = " + res1);
				result.append(res1);
			}
		}
		return result.toString();
	}
	
	/**
	 * 转2进制(字符串转成二进制)
	 * @param text 要转的文本
	 * @return
	 */
	public static String strtoBinary(String text) {
    
    
		StringBuilder result = new StringBuilder("");
		//取每一位上的数字
		for(char ch : text.toCharArray()) {
    
    
			int res = ch, pre = ch;
			String res1 = "";
			while(res > 0) {
    
    
				res = res >> 1 << 1;
				res1 = ((pre ^ res) == 0 ? "0" : "1") + res1; //异或判断当前位上数字是否为1
				res = res >> 1;
				pre = pre >> 1;
			}
			//扩充至8位
			while (res1.length() < 8) {
    
    
				res1 = "0" + res1;
			}
//			System.out.println("res1 = " + res1);
			result.append(res1);
		}
		return result.toString();
	}
	
	/**
	 * 转字符串(二进制转成字符串)
	 * @param encodedText 二进制文本
	 * @return
	 */
	public static String binaryToStr(String encodedText) {
    
    
		int count = 8,chNum = 0;
		StringBuilder result = new StringBuilder("");
		//取每一位上的数字
		for(char ch : encodedText.toCharArray()) {
    
    
			chNum += (ch - '0') << (--count);
//			System.out.println("count=" + count);
//			System.out.println("ch=" + ch);
//			System.out.println("chNum=" + chNum);
			if (count == 0) {
    
    
				count = 8;
				char res = (char)chNum;
				result.append(res);
				chNum = 0;
			}	
		}
		return result.toString();
	}

	/**
	 * 判断是否属于该进制
	 * @param text 要转的文本
	 * @param radix 原进制
	 * @return
	 */
	private static boolean verifyRadix(String text, EncodeRadix radix) {
    
    
		int value = radix.getValue();
		String str = new String(HEX_TABLE);
		for(char ch : text.toCharArray()) {
    
    
			int index = str.indexOf(ch);
			if (index <0 || index >= value) {
    
    
				return false;
			}
		}
		return true;
	}
	
	public static void main(String[] args) {
    
    
		System.out.println(toBinary("123456789", EncodeRadix.HEX));
	}
}

————————————————Little Tail ——————————————————
To be continued

Guess you like

Origin blog.csdn.net/qq_31236027/article/details/128579451