这个问题已经存在了一段时间,如果我可以让它工作,我认为我应该提供一些奖励积分.
最近在工作中,我写了一个解析器,它将以可读格式转换二进制文件.二进制文件不是带10101010字符的Ascii文件.它已经以二进制编码.所以如果我cat在文件上做一个,我得到以下 -
[jaypal~/Temp/GTP]$ cat T20111017153052.NEW
==?sGTP???N????W????&Xx1?T?&Xx1?;
?d@#e?
?0H????????|?X?@@(????VtPOC01
cceE??k@9??W???R?K?i2??d@#e???&Xx1&Xx??!?
blackberrynet?/??!
??!
??#ripassword??W??W???0H??
#R??@Vtc@@(????n?POC01
Run Code Online (Sandbox Code Playgroud)
所以我使用hexdump实用程序使文件显示在内容之后并将其重定向到文件.现在我的输出文件是一个包含Hex值的文本文件.
[jaypal~/Temp/GTP]$ hexdump -C T20111017153052.NEW
00000000 3d 3d 01 f8 73 47 54 50 02 f1 d5 b2 be 4e e4 d7 |==..sGTP.....N..|
00000010 00 01 01 00 01 80 00 cc 57 e5 82 00 00 00 00 00 |........W.......|
00000020 00 00 00 00 00 00 00 00 87 d3 f5 13 00 00 00 00 |................| …Run Code Online (Sandbox Code Playgroud) 我需要从一组嵌套配置值创建一个标识符令牌。\n该令牌可以是 URL 的一部分,因此 \xe2\x80\x93 为了使处理更容易 \xe2\x80\x93 它应该只包含十六进制数字(或类似的东西)。\n配置值是嵌套元组,其中包含可哈希类型的元素int,例如bool、str等。
我的想法是使用内置hash()函数,因为即使配置结构发生变化,它也将继续工作。\n这是我的第一次尝试:
def token(config):\n h = hash(config)\n return '{:X}'.format(h)\nRun Code Online (Sandbox Code Playgroud)\n\n这将产生可变长度的标记,但这并不重要。\n不过,令我困扰的是该标记可能包含一个前导减号,因为 的返回值是hash()一个有符号整数。
作为避免该符号的一种方法,我想到了以下解决方法,即向哈希值添加一个常量。\n该常量应该是值可以采用的范围大小的一半hash()(这是依赖于平台的,例如,32 位/64 位系统有所不同):
HALF_HASH_RANGE = 2**(sys.hash_info.width-1)\nRun Code Online (Sandbox Code Playgroud)\n\n这是一个理智且便携的解决方案吗?\n或者我会用这个搬起石头砸自己的脚吗?
\n\n我还看到了使用的建议struct.pack()(它返回一个bytes对象,可以在该对象上调用该.hex()方法),但它还需要提前知道哈希值的范围(以便选择正确的格式字符)。
附录:
\n加密强度或偶然的冲突不是问题。\nhashlib在这种情况下,该库的缺点是它需要编写一个转换器来遍历输入结构并将所有内容转换为bytes表示形式,这很麻烦。
如何更改hexdump默认16(到21)中打印的列数?
或者我在哪里可以找到更改默认格式字符串的地方hexdump,以便修改在那里使用的数字?
以下*nix命令将一个IP和端口(127.0.0.1:80)的十六进制表示形式管道到hexdump命令中.
printf "\x7F\x00\x00\x01\x00\x50" | hexdump -e '3/1 "%u." /1 "%u:" 1/2 "%u" "\n"'
Run Code Online (Sandbox Code Playgroud)
-e标志允许任意格式解析输入.在这种情况下,我们将IP的前三个八位字节解析为无符号小数,后跟一个点.最后的八位字节也被解析为无符号小数,但后面跟一个冒号.最后 - 这就是问题所在 - 端口的2个字节被解析为单个无符号小数后跟换行符.
根据执行此命令的系统的字节顺序,结果会有所不同.一个大端系统将正确显示端口80; 而小端系统将显示端口20480.
有没有办法操纵hexdump以了解字节顺序,同时仍允许通过-e进行任意格式规范?
我在SQLite表中有一列数据存储为blob.具体来说,它是一个序列化的POJO(java对象).
无论哪种方式,我想在SQLite控制台中将其视为十六进制转储,有点像这样:
0000000000 |The correction f|
0000000016 |or the aberratio|
0000000032 |n of light is sa|
0000000048 |id,.on high auth|
0000000064 |ority, not to be|
0000000080 | perfect even in|
0000000096 | that most perfe|
0000000112 |ct organ, the.ey|
0000000128 |e..|
Run Code Online (Sandbox Code Playgroud)
我知道该语句SELECT HEX(obj) FROM data WHERE rowid = 1会将数据视为十六进制,但现在我想把它管道化为能给我一个hexdump视图的东西.
PS - 我知道我试图查看的数据是二进制(序列化POJO),但我想看看里面的实验是什么.所以,即使最终结果是神秘的,请告诉我!
更新:我尝试了一些建议,但发现sqlite3没有输出完整的十六进制.我期待大约500字节,但改为10:
root@ubuntu:~# sqlite3 IceCream.db "select hex(obj) from Customers where rowid=1;"
ACED00057372002D6564752E6761746563682E7365636C6173732E70726F6A656374322E637573746F6D65722E437573746F6D6572000000000000000102000B4C0007616464726573737400124C6A6176612F6C616E672F537472696E673B4C0012617661696C61626C65467265654974656D737400134C6A6176612F6C616E672F496E74656765723B4C00096269727468446174657400104C6A6176612F7574696C2F446174653B4C000C646973636F756E745261746571007E00024C000966697273744E616D6571007E00014C000A676F6C645374617475737400134C6A6176612F6C616E672F426F6F6C65616E3B4C00086C6173744E616D6571007E00014C000D6D6F6E74686C79506F696E747371007E00024C0013706F696E74734561726E656450657254696D657400134C6A6176612F7574696C2F486173684D61703B4C000B746F74616C506F696E747371007E00024C000876697053696E636571007E0003787200386564752E6761746563682E7365636C6173732E70726F6A656374322E73797374656D732E446174616261736553657269616C4F626A65637400000000000000010200024C000269647400104C6A6176612F6C616E672F4C6F6E673B4C00166C61737454696D654F626A6563744D6F64696669656471007E000778707372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B020000787000000000000000017371007E0009000001497757AAFB740006436172736F6E737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C75657871007E000A000000007372000E6A6176612E7574696C2E44617465686A81014B59741903000078707708000001349BB816607871007E000F74000442696C6C737200116A6176612E6C616E672E426F6F6C65616ECD207280D59CFAEE0200015A000576616C7565787000740005313233205471007E000F737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000146000A6C6F6164466163746F7278703F400000770800000010000000007871007E000F70
root@ubuntu:~# sqlite3 IceCream.db "select obj from Customers where rowid=1;" | hexdump -C
00000000 ac ed …Run Code Online (Sandbox Code Playgroud) 为了更多地了解C,过去两天我一直在玩它.我想开始研究C在运行时是如何构造的,所以我构建了一个糟糕的程序,要求用户输入两个整数值,然后输出整数变量的内存位置.然后我想验证数据是否真的存在,我将程序暂停了getchar()以打开GDB并挖掘内存段以验证数据但是,这些位置的数据没有多大意义我.有人可以解释这里发生了什么.
#include <stdio.h>
void pause();
int main() {
int a, b;
printf("Please enter number one:");
scanf("%d", &a);
printf("Please enter number two:");
scanf("%d", &b);
printf("number one is %d, number two is %d\n", a, b);
// find the memory location of vairables:
printf("Address of 'a' %pn\n", &a);
printf("Address of 'b' %pn\n", &b);
pause();
}
void pause() {
printf("Please hit enter to continue...\n");
getchar();
getchar();
}
Run Code Online (Sandbox Code Playgroud)
[josh@TestBox c_code]$ ./memory
Please enter number one:265
Please enter number two:875
number one is 265, …Run Code Online (Sandbox Code Playgroud) 我有一个二进制文件,其中包含编码为不同长度(主要是 2-/4-字节)的有符号或无符号整数的数值。为了处理这些数据,我将文件的所需部分作为raw向量读取readBin(),然后尝试将其转换为十进制。问题是,R内置函数有限制,我不完全理解(例如没有 long unsigned ints) - 请参阅下面的示例。
如何int从原始数据中读取自定义长度的 unsigned s?有没有比下面指定的更合适、更优雅的方法?
require(dplyr)
###############################################################################
# create examplary raw vector of 24 bytes
set.seed(1)
raw <- sample(0:0xff, 24, T) %>% as.raw %>% print
###############################################################################
# approach with readBin() - not working
# read 2-byte unsigned integers left-to-right, not an issue
readBin(raw, size = 2, n = length(raw) / 2, integer(), endian = 'big', signed = FALSE)
# read 4-byte signed integers left-to-right, it's ok …Run Code Online (Sandbox Code Playgroud) 我的所有代码都在源代码管理下,所以我100%确定源代码没有改变.但是如果我构建一个C#DLL两次,它们的内容就会略有不同.我可以通过构建,然后再次构建,100%的时间重现问题.
这似乎根本不会对程序产生影响,但是用于从两个MSI文件创建补丁的MSIMSP等工具会因这些微小的更改而被抛弃.制作补丁(对于我的产品)比它们应该大40倍.
我已经反编译了这两个DLL及其汇编信息,类等等......完全相同.文件大小也完全相同,但当然有不同的创建时间.所以我真的无法理解发生了什么变化.
所以我挖了一点.
我已经使用WinDiff查找更改,然后在十六进制编辑器中交叉引用这些更改.WinDiff显示第二个"行"的变化,并在文件的大约80%的行中显示.
在十六进制编辑器中,我看到更改的第一个字节是字节0x088(字节136).这似乎是这条'线'上唯一改变的字节.我找不到第二个更改,因为WinDiff没有告诉我更改的确切字节偏移量.
是否有人熟悉(C#)DLL文件的组成知道更改的字节可能意味着什么?或者更好的是如何确保DLL文件在重建时保持完全相同?
我需要获取我拥有的文件的十六进制值。
在 Linux 上,这很简单:
hexdump -ve '1/1 "%.2x"' Filename
Run Code Online (Sandbox Code Playgroud)
然而,在 Windows 上,我找不到 hexdump 的良好等效项。我正在使用 MinGW64,所以基本上我正在寻找一个 hexdump.exe,我可以简单地将其添加到我的 MinGW 存储库中。我确实找到了其中两个,但没有一个与 linux 相同;他们就像hexdump -C
那么,你知道一个很好的等价物,或者一种通过其他功能获得我想要的东西的方法吗?(但没有 PowerShell 功能)。我得到了 sed 和 awk 如果这有帮助的话......
这是一个例子;如果我有这个名为 TEST 的文件:
测试:
test test test
Run Code Online (Sandbox Code Playgroud)
然后我想得到这个结果:
746573742074657374207465737420
Run Code Online (Sandbox Code Playgroud)
(没有任何换行符)
我目前正在处理一些二进制数据。为了检查和调试我的应用程序先前生成的数据,我使用hexdump,面临 hexdump 似乎无法提取 64 位整数字段的障碍。鉴于以下最小示例:
#include <iostream>
#include <fstream>
#include <cstdint>
int main(int argc, char** argv){
std::ofstream os("tmp.bin", std::ios::out | std::ios::binary);
uint64_t x = 7;
os.write((char*)&x,sizeof(uint64_t));
os.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在我的系统上执行一个简单的十六进制转储:
hexdump tmp.bin
> 0000000: 0007 0000 0000 0000
> 0000008:
Run Code Online (Sandbox Code Playgroud)
现在尝试提取 64 位宽度的 unsigned int 产生:
hexdump -e '/8 "%u"' tmp.bin
> hexdump: bad byte count for conversion character u
Run Code Online (Sandbox Code Playgroud)
根据David Mair写得很好的hexdump-manual应该可以做到,但我没有成功。
我错过了什么?