天天看點

java、C/C++/Objective-c 進制轉換

/**
		<p>
		最近遇到一個問題 C/C++/Objective-c中的資料類型 16進制資料到java中進行轉換</p><p>
		在java總轉換 C 中無符号好辦,直接用java中的類型轉換就行了如 c中無符号Int32 java中 Long.parseLong("FFFF",16)即可</p><p>
		但是碰到一個有符号的 ,就是C中 int類型負數的情況</p><p>
		這裡我的解決方案是可以轉過來的,但是有個限制(java、c中的int值都在 -128~127這個
		取值範圍 通過&位與操作可以得到這個範圍中的正确資料)</p><p>
		java中 -3:fffffffd; -83:ffffffad(int:16進制)</p><p>
		C中 -3:fdff ;-83:adff</p><p>
		發現很郁悶的事情 轉換的時候需要異位一下才可以,下面貼上代碼來驗證處理結果</p>
		*/
		public static void main(String[] args) {
			/*
			 * 正數處理
			 */
			System.out.println(Integer.toHexString(127)); // 轉換成16進制為 7f 傳到C++那邊必須是 7fff才能保持一緻
			System.out.println(parseInt("7fff")); // 在java中通過異位 即ff7f轉換回來就是 127
	
			/*
			 * 負數處理 
			 * <p>負數十六進制轉換也同樣可以(但是注意int值必須在-128~127這個取值範圍, 因為通過byte範圍是-128~127超出的部分處理出來的就是髒資料)</p>
			 */
			System.out.println(Integer.toHexString(-5)); // 16進制為fffffffb
			System.out.println(parseInt("fbff")); // 轉換回來就是 -5
	
			/*
			 * 中文16進制直接轉換 網上看到的感覺比較不錯
			 */
			System.out.println(encode("中文")); // D6D0CEC4十六進制
			System.out.println(decode(encode("中文")));
		}
	
		/**
		 * 有符号轉換
		 * 
		 * @param data
		 *            4位大小
		 * @return
		 */
		private static int parseInt(String data) {
			String dd = data.substring(2) + data.substring(0, 2);
			int temp = 0;
			try {
				temp = Integer.valueOf(dd, 16);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return (byte) (temp & 0xFF);
		}
	
		/**
		 * <span style="color:blue">資料異位 與C/C++中16進制資料保持一緻</span>
		 * 
		 * @param data
		 * @return
		 */
		private String convertHexString(String data) {
			int sum = data.length();
			switch (sum) {
			case 1:
				return "0" + data + "00";
			case 2:
				return data + "00";
			case 3:
				return data.substring(1) + "0" + data.substring(0, 1);
			case 4:
				return data.substring(2) + data.substring(0, 2);
			case 8:
				return data.substring(6) + data.substring(4, 6);
			default:
				break;
			}
			return null;
		}
		
		/*
		 * 将16進制數字解碼成字元串,适用于所有字元(包括中文)
		 */
		public static String decode(String bytes) {
			ByteArrayOutputStream baos = new ByteArrayOutputStream(
					bytes.length() / 2);
			// 将每2位16進制整數組裝成一個位元組
			for (int i = 0; i < bytes.length(); i += 2)
				baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
						.indexOf(bytes.charAt(i + 1))));
			return new String(baos.toByteArray());
		}
			
		/*
		 * 16進制數字字元集
		 */
		private static String hexString = "0123456789ABCDEF";
	
		/*
		 * 将字元串編碼成16進制數字,适用于所有字元(包括中文)
		 */
		public static String encode(String str) {
			// 根據預設編碼擷取位元組數組
			byte[] bytes = str.getBytes();
			StringBuilder sb = new StringBuilder(bytes.length * 2);
			// 将位元組數組中每個位元組拆解成2位16進制整數
			for (int i = 0; i < bytes.length; i++) {
				sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
				sb.append(hexString.charAt((bytes[i] & 0x0f) >> 0));
			}
			return sb.toString();
		}
	/*	
		下面那個網站找到的 感覺挺不錯 
		十進制轉成十六進制: 
		Integer.toHexString(int i) 
		十進制轉成八進制 
		Integer.toOctalString(int i) 
		十進制轉成二進制 
		Integer.toBinaryString(int i) 
		十六進制轉成十進制 
		Integer.valueOf("FFFF",16).toString() 
		八進制轉成十進制 
		Integer.valueOf("876",8).toString() 
		二進制轉十進制 
		Integer.valueOf("0101",2).toString() 
		
		
		有什麼方法可以直接将2,8,16進制直接轉換為10進制的嗎? 
		java.lang.Integer類 
		parseInt(String s, int radix) 
		使用第二個參數指定的基數,将字元串參數解析為有符号的整數。 
		examples from jdk: 
		parseInt("0", 10) returns 0 
		parseInt("473", 10) returns 473 
		parseInt("-0", 10) returns 0 
		parseInt("-FF", 16) returns -255 
		parseInt("1100110", 2) returns 102 
		parseInt("2147483647", 10) returns 2147483647 
		parseInt("-2147483648", 10) returns -2147483648 
		parseInt("2147483648", 10) throws a NumberFormatException 
		parseInt("99", throws a NumberFormatException 
		parseInt("Kona", 10) throws a NumberFormatException 
		parseInt("Kona", 27) returns 411787 
		
		
		進制轉換如何寫(二,八,十六)不用算法 
		Integer.toBinaryString 
		Integer.toOctalString 
		Integer.toHexString 
		*/