關於字串轉16進位 [論壇 - 新手村]


正在瀏覽:   1 名遊客


 到底部   前一個主題   下一個主題  [無發表權] 請登錄或者註冊



關於字串轉16進位
會員一級
註冊日期:
2013/10/21 16:01
所屬群組:
已註冊使用者
等級: 2
HP : 0 / 49
MP : 6 / 1360
EXP: 97
離線
原本想把附近中的二進位全部改成十六進位

資料都是36個數字 想轉乘9個十六進位的表示法

原本的想法是用fget把每一行抓出來 再用itoa()的函式去轉換

可是linux好像沒有支援itoa()這個函式

想請問大家一下 是否還有其他以經既有的func()去做轉換 而不用自己寫一個hash出來

謝謝大家

http://imgur.com/qgSsqet

附件:



png  圖片1.png (328.98 KB)
36684_54feb0f3e87f2.png 1350X685 px

2015/3/10 16:54
應用擴展 工具箱
回覆: 關於字串轉16進位
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 36
HP : 179 / 898
MP : 664 / 28634
EXP: 92
離線
查詢「itoa php」查到一篇在官方文件上的「Comment」。

關於編碼,我不懂,只是路過,查個資料,順手貼上,待其他人解答



Daneinei 寫到:
原本想把附近中的二進位全部改成十六進位

資料都是36個數字 想轉乘9個十六進位的表示法

原本的想法是用fget把每一行抓出來 再用itoa()的函式去轉換

可是linux好像沒有支援itoa()這個函式

想請問大家一下 是否還有其他以經既有的func()去做轉換 而不用自己寫一個hash出來

謝謝大家

http://imgur.com/qgSsqet

2015/3/10 17:51
應用擴展 工具箱
回覆: 關於字串轉16進位
會員四級
註冊日期:
2010/8/12 15:54
所屬群組:
已註冊使用者
等級: 18
HP : 0 / 443
MP : 135 / 16323
EXP: 72
離線
指令 bc

echo "ibase=16;obase=2;1010"|bc
這行意思是:輸入二進位值1010; 輸出轉成16進位

其它應該可以自己來吧

2015/3/10 18:40
應用擴展 工具箱
回覆: 關於字串轉16進位
會員二級
註冊日期:
2009/6/22 14:07
所屬群組:
已註冊使用者
等級: 8
HP : 0 / 179
MP : 28 / 7211
EXP: 18
離線
如果是 C 語言的話,我會用 strtol 加 fprintf 來做

簡單範例:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   fprintf(stdout, "%#011lX\n", strtol("000000000000000000000000000000001011", NULL, 2));
   return 0;
}


輸出如下:
$ gcc  test.c && ./a.out
0X00000000B


把 stdout 改成 file pointer 就可以把轉完的資料輸出到檔案了

如果不想要前置 0X 的話,就把 %#011lX 改成 %09lX (或 %09lx)

還有為什麼你的二進位資料有一堆 x ?

2015/3/10 19:14
應用擴展 工具箱
回覆: 關於字串轉16進位
會員一級
註冊日期:
2013/10/21 16:01
所屬群組:
已註冊使用者
等級: 2
HP : 0 / 49
MP : 6 / 1360
EXP: 97
離線
OK了 謝謝Choco大的幫忙

我裡面有XX是因為原本設定有threshold

如果比threshold小就捨棄 所以設為XX

fprintf 和 strtol兩種我ㄧ開始都有找到

可是應該是我資料結構的問題 ㄧ直會有bug...orz

acman的那個語法 我還在研究lol

不過謝謝兩位的幫忙 讓我上了ㄧ課

2015/3/11 10:57
應用擴展 工具箱
回覆: 關於字串轉16進位
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 36
HP : 179 / 898
MP : 664 / 28634
EXP: 92
離線
acman 寫到:
指令 bc

echo "ibase=16;obase=2;1010"|bc
這行意思是:輸入二進位值1010; 輸出轉成16進位

其它應該可以自己來吧


上面的會顯示

1000000010000



想釐清確認一下,上面的是不是寫顛倒了。


echo "ibase=2;obase=16;1010" | bc



顯示


101



但還是覺得怪怪的,所以用了「bc ibase」查到了「這篇」。

「obase」和「ibase」的順序改一下,就OK了


echo "obase=16;ibase=2;1010" | bc



就會顯示


A



用10進位驗證一下


echo "obase=10;ibase=2;1010" | bc



顯示


10




1010 = 8 + 0 + 2 + 0 = 10





## 更多參考

* 鳥哥的 Linux 私房菜 / 第五章、首次登入與線上求助 man page / 簡單好用的計算機: bc
* man bc

2015/3/11 13:34
應用擴展 工具箱
回覆: 關於字串轉16進位
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 36
HP : 179 / 898
MP : 664 / 28634
EXP: 92
離線
對不起!

先致歉一下!

一開始回這個問題的時候,沒有好好看清楚樓主要的。

哪時候我眼中只有看到「itoa」,所以就順手查了一下「itoa php」查到一篇在官方文件上的「Comment」。

那時候沒想太多。

剛靜下心來看。

php內建就有一個轉換的函式「base_convert」。

所以PHP的版本可以這樣寫


<?php
# test.php
$src = '1010';
$des = base_convert($src, 2, 16);
echo $des;
?>



安裝「php5-cli


$ sudo apt-get install php5-cli



執行剛剛寫好的php script。


$ php test.php



就會顯示


a



以上



以下是簡單的實作樓主的需求,當作參考摟

因為不懂「threshold 」的作用,所以就暫時略過,假設每一行都是類似「000000000000000000000000000000001011」這樣的格式。

另外偷懶直接用file來實作 :-p

Daneinei 寫到:
我裡面有XX是因為原本設定有threshold

如果比threshold小就捨棄 所以設為XX




#!/usr/bin/env php
<?php
// bin_to_hex.php
function bin_to_hex($val)
{
return sprintf("%09s", base_convert($val, 2, 16));
}

function file_bin_to_hex($src, $des)
{
$rtn = '';
$list = file($src);

foreach ($list as $key => $val) {
$rtn .= bin_to_hex($val);
$rtn .= PHP_EOL;
}
file_put_contents($des, $rtn);
}

function usage()
{
echo 'php bin_to_hex.php [source_file] [target_file]';
}

if ($argc < 3) {
usage();
exit;
}

$src = $argv[1];
$des = $argv[2];

if (!$src) {
usage();
exit;
}

if (!$des) {
usage();
exit;
}

file_bin_to_hex($src, $des);
?>




可以執行


$ php bin_to_hex.php src.txt des.txt



或是


$ chmod u+x bin_to_hex.php
$ bin_to_hex.php src.txt des.txt




完畢收工



samwhelp 寫到:
查詢「itoa php」查到一篇在官方文件上的「Comment」。

關於編碼,我不懂,只是路過,查個資料,順手貼上,待其他人解答



Daneinei 寫到:
原本想把附近中的二進位全部改成十六進位

資料都是36個數字 想轉乘9個十六進位的表示法

原本的想法是用fget把每一行抓出來 再用itoa()的函式去轉換

可是linux好像沒有支援itoa()這個函式

想請問大家一下 是否還有其他以經既有的func()去做轉換 而不用自己寫一個hash出來

謝謝大家

http://imgur.com/qgSsqet

2015/3/11 14:06
應用擴展 工具箱
回覆: 關於字串轉16進位
會員四級
註冊日期:
2010/8/12 15:54
所屬群組:
已註冊使用者
等級: 18
HP : 0 / 443
MP : 135 / 16323
EXP: 72
離線
samwhelp 寫到:
acman 寫到:
指令 bc

echo "ibase=16;obase=2;1010"|bc
這行意思是:輸入二進位值1010; 輸出轉成16進位

其它應該可以自己來吧


上面的會顯示

1000000010000



想釐清確認一下,上面的是不是寫顛倒了。




感謝糾正!!是我寫巔倒了

2015/3/11 16:30
應用擴展 工具箱
回覆: 關於字串轉16進位
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 36
HP : 179 / 898
MP : 664 / 28634
EXP: 92
離線
acman 寫到:
samwhelp 寫到:
acman 寫到:
指令 bc

echo "ibase=16;obase=2;1010"|bc
這行意思是:輸入二進位值1010; 輸出轉成16進位

其它應該可以自己來吧


上面的會顯示

1000000010000



想釐清確認一下,上面的是不是寫顛倒了。




感謝糾正!!是我寫巔倒了




感謝你又讓我學會一招

以下是用「shell script」的方式來寫。

## 參考資料

因為不熟「shell script」,所以找了一下資料,拼湊出要達成的效果。

* 用「bash read file line by line」查到一篇「Bash Scripting & Read File line by line」。
* 用「shell 補0」查到一篇「shell如何實現 數字 字符串自動補零 awk

## 前置作業

產生測試檔案


touch src.txt
echo 000000000000000000000000000000001011 >> src.txt
echo 000000000000000000000000000000001010 >> src.txt
echo 000000000000000000000000000000011010 >> src.txt
echo 001000000000000000000000000000001011 >> src.txt
echo 100000000000000000000000000000001011 >> src.txt



## 半成品 (printf版)


#!/bin/bash
# bin_to_hex.printf.semi.sh
while read line
do
src=$line
des=`echo "obase=16;ibase=2;$src" | bc`
printf "%09s\n" $des # 只有補空白的效果
#printf "%09x\n" $des # 這一行會出錯
#printf "%09d\n" $des # 這一行會出錯
done < $1




測試


$ ./bin_to_hex.printf.semi.sh src.txt



會顯示(1,2,3行應該是會補空白,但這個論壇我不知道要怎麼弄前面有空白)


B
A
1A
20000000B
80000000B




## 半成品 (awk版)


#!/bin/bash
# bin_to_hex.awk.sh
while read line
do
src=$line
echo "obase=16;ibase=2;$src" | bc | awk '{printf("%09s\n", $0)}' # 只有補空白的效果
#echo "obase=16;ibase=2;$src" | bc | awk '{printf("%09d\n", $0)}' # 有些數值不正確
#echo "obase=16;ibase=2;$src" | bc | awk '{printf("%09x\n", $0)}' # 有些數值不正確
done < $1



測試


$ ./bin_to_hex.awk.semi.sh src.txt



會顯示(1,2,3行應該是會補空白,但這個論壇我不知道要怎麼弄前面有空白)


B
A
1A
20000000B
80000000B




因為上面的方式,找不到16進位補0的方式,最多只能作到補空白。
所以改另一個方式就行得通了,先轉成10進位,然後再用「%09x」來格式輸出。


## 完成品 (printf版)


#!/bin/bash
# bin_to_hex.printf.sh
while read line
do
src=$line
des=`echo "obase=10;ibase=2;$src" | bc` # 先轉成10進位數值
printf "%09x\n" $des # 利用printf轉成16進位,並且可以補0
done < $1



測試


$ ./bin_to_hex.printf.sh src.txt



會顯示


00000000b
00000000a
00000001a
20000000b
80000000b




## 完成品 (awk版)


#!/bin/bash
# bin_to_hex.awk.sh
while read line
do
src=$line
echo "obase=10;ibase=2;$src" | bc | awk '{printf("%09x\n", $0)}'
done < $1




測試


$ ./bin_to_hex.awk.sh src.txt



會顯示


00000000b
00000000a
00000001a
20000000b
80000000b



若要存到新的檔,重導就好了


$ ./bin_to_hex.awk.sh src.txt > des.txt




完畢




## 更多參考

$ type printf


printf is a shell builtin




$ whatis printf


printf (3) - formatted output conversion
printf (1) - format and print data
printf (1posix) - write formatted output
printf (3posix) - print formatted output



* man 1 printf
* man 3 printf
* man 1posix printf
* man 3posix printf


$ whatis bc


bc (1) - An arbitrary precision calculator language
BC (3ncurses) - direct curses interface to the terminfo capability database
bc (1posix) - arbitrary-precision arithmetic language



* man 1 bc
* man 1posix bc
* info bc


$ whatis awk


awk (1) - pattern scanning and text processing language
awk (1posix) - pattern scanning and processing language



* man 1 awk
* man 1posix awk


$ sudo apt-get install gawk-doc

* info gawk

2015/3/12 3:27
應用擴展 工具箱


 [無發表權] 請登錄或者註冊


可以查看帖子.
不可發帖.
不可回覆.
不可編輯自己的帖子.
不可刪除自己的帖子.
不可發起投票調查.
不可在投票調查中投票.
不可上傳附件.
不可不經審核直接發帖.