使用bash:将整数的位表示写入文件

时间:2010-04-30 18:18:12

标签: bash unix stdout binaryfiles

我有一个包含二进制数据的文件,我需要在某个位置替换几个字节。我已经拿出以下内容将bash指向偏移并告诉我它找到了我想要的地方:

dd bs=1 if=file iseek=24 conv=block cbs=2 | hexdump

现在,使用“file”作为输出:

echo anInteger | dd bs=1 of=hextest.txt oseek=24 conv=block cbs=2

这似乎工作正常,我可以查看十六进制编辑器中所做的更改。问题是,“anInteger”将被写为该整数的ASCII表示(这是有道理的)但我需要编写二进制表示。

我想为此使用bash,脚本应该在尽可能多的系统上运行(我不知道目标系统是否会安装python或其他任何东西)。

如何告诉命令将输入​​转换为二进制(可能是十六进制)?

9 个答案:

答案 0 :(得分:14)

printfecho更便携。此函数采用十进制整数并输出具有该值的字节:

echobyte () {
    if (( $1 >= 0 && $1 <= 255 ))
    then
        printf "\\x$(printf "%x" $1)"
    else
        printf "Invalid value\n" >&2
        return 1
    fi
}

$ echobyte 97
a
$ for i in {0..15}; do echobyte $i; done | hd
00000000  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
00000010

答案 1 :(得分:11)

您可以使用echo使用十六进制或八进制发出特定字节。例如:

echo -n -e \\x30 

将打印ascii 0(0x30)

( - n删除尾随换行符)

答案 2 :(得分:6)

xxd是更好的方法。 xxd -r infile outfile将infile中的ascii十六进制值作为补丁输出文件,您可以通过以下方式指定infile中的具体位置:1FE:55AA

答案 3 :(得分:5)

工作就像一种享受。我使用以下代码在小端的字节24处用两个整数(1032和1920)替换4个字节。代码不会截断文件。

echo -e \\x08\\x04\\x80\\x07 | dd of=<file> obs=1 oseek=24 conv=block,notrunc cbs=4

再次感谢。

答案 4 :(得分:0)

如果你愿意依赖bc(这很常见)

echo -e "ibase=16\n obase=2 \n A1" | bc -q

可能有帮助。

答案 5 :(得分:0)

您可以将所需的输入放入文件中,并使用dd的“if =”选项准确插入所需的输入。

答案 6 :(得分:0)

我有一个功能:

window.addEventListener('load', initialise)

//Initialises the map view
function initialise() {
    var mapOptions = {
        center: new google.maps.LatLng(53.4113594, -2.1571162),
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    //Creates the actual Map object
    var map = new google.maps.Map(document.getElementById("mapArea"), mapOptions);


    setMarkers(map, myLocations);
}
var myLocations = [
    ['Stockport Town Hall', 'This is the town hall. Where things... happen.', 'townhall.jpg', 53.406, -2.158215, 'images/markers/townhall.png'],
    ['Stockport Town Centre', 'This is the centre of town. Where there are shops. And food. and... stuff', 'stockportcentre.jpg', 53.4175146, -2.1490619,
        'images/markers/shopping.png'
    ],
    ['Stockport College', 'This is Stockport college. Where learning happens.', 'stockportcollege.jpg', 53.4040427, -2.1587963, 'images/markers/Learning.png'],
    ['Stockport Train station', 'This is the train station. Where you catch trains.', 'stockporttrainstation.jpg', 53.4056234, -2.1637525, 'images/markers/train.png']

];



function setMarkers(map, myLocations) {
    for (var i in myLocations) {
        var name = myLocations[i][0];
        var info = myLocations[i][1];
        var image = myLocations[i][2];
        var lat = myLocations[i][3];
        var lng = myLocations[i][4];
        var indivIcon = myLocations[i][5];
        var latlngset;
        latlngset = new google.maps.LatLng(lat, lng);

        var marker = new google.maps.Marker({
            map: map,
            title: name,
            position: latlngset,
            icon: indivIcon
        });


        //content here!

        var infoContent = '<h3>' + name + '</h3>' + info +
            '<br /><img width = "128" height = "128" src = "images/' + image + ' " ' + '</div>';



        var infowindow = new google.maps.InfoWindow();

        google.maps.event.addListener(
            marker, 'click',
            function() {
                infowindow.setContent(infoContent);
                infowindow.open(map, this);
            });

    }
}

您可以使用管道或重定向来捕获结果。

答案 7 :(得分:0)

用bash,&#34; printf&#34;有&#34; -v&#34;选项,所有shell都有逻辑运算符。

所以这里是bash中更简单的形式:

int2bin() {
  local i=$1
  local f
  printf -v f '\\x%02x\\x%02x\\x%02x\\x%02x' $((i&255)) $((i >> 8 & 255)) $((i >> 16 & 255)) $((i >> 24 & 255))
  printf "$f"
}

答案 8 :(得分:0)

就我而言,我需要从十进制数字参数到实际的无符号16位大端值。这可能不是最有效的方式,但它有效:

false