2010-09-22 8 views
17

पर बाइनरी स्वरूपित करना क्या मैं एक एरलांग बाइनरी प्रारूपित कर सकता हूं ताकि प्रत्येक बाइट हेक्स में लिखा जा सके? अर्थात, औरएरलांग आईओओ: हेक्स

> io:format(???, [<<255, 16>>]). 
<<FF, 10>> 

मैं io:format दस्तावेज में यह करने के लिए एक स्पष्ट रास्ता नहीं दिख रहा है, लेकिन शायद मैं बस एक याद आ रही है? एक बाइनरी को सूची में बदलने और अपने तत्वों को अलग-अलग स्वरूपित करना बहुत अक्षम है।

उत्तर

21

नहीं, इस तरह के formating विकल्प नहीं है, लेकिन आप की तरह कुछ कर सकते हैं:

io:format("<<~s>>~n", [[io_lib:format("~2.16.0B",[X]) || <<X:8>> <= <<255,16>> ]]). 

अगर आप की जरूरत है बहुत तेजी से समाधान नहीं है।

-module(bin_to_hex). 

-compile([native, {hipe, [o3]}]). 

-export([bin_to_hex/1]). 

bin_to_hex(B) when is_binary(B) -> 
    bin_to_hex(B, <<>>). 

-define(H(X), (hex(X)):16). 

bin_to_hex(<<>>, Acc) -> Acc; 
bin_to_hex(Bin, Acc) when byte_size(Bin) band 7 =:= 0 -> 
    bin_to_hex_(Bin, Acc); 
bin_to_hex(<<X:8, Rest/binary>>, Acc) -> 
    bin_to_hex(Rest, <<Acc/binary, ?H(X)>>). 

bin_to_hex_(<<>>, Acc) -> Acc; 
bin_to_hex_(<<A:8, B:8, C:8, D:8, E:8, F:8, G:8, H:8, Rest/binary>>, Acc) -> 
    bin_to_hex_(
    Rest, 
    <<Acc/binary, 
     ?H(A), ?H(B), ?H(C), ?H(D), ?H(E), ?H(F), ?H(G), ?H(H)>>). 

-compile({inline, [hex/1]}). 

hex(X) -> 
    element(
    X+1, {16#3030, 16#3031, 16#3032, 16#3033, 16#3034, 16#3035, 16#3036, 
      16#3037, 16#3038, 16#3039, 16#3041, 16#3042, 16#3043, 16#3044, 
      16#3045, 16#3046, 16#3130, 16#3131, 16#3132, 16#3133, 16#3134, 
      16#3135, 16#3136, 16#3137, 16#3138, 16#3139, 16#3141, 16#3142, 
      16#3143, 16#3144, 16#3145, 16#3146, 16#3230, 16#3231, 16#3232, 
      16#3233, 16#3234, 16#3235, 16#3236, 16#3237, 16#3238, 16#3239, 
      16#3241, 16#3242, 16#3243, 16#3244, 16#3245, 16#3246, 16#3330, 
      16#3331, 16#3332, 16#3333, 16#3334, 16#3335, 16#3336, 16#3337, 
      16#3338, 16#3339, 16#3341, 16#3342, 16#3343, 16#3344, 16#3345, 
      16#3346, 16#3430, 16#3431, 16#3432, 16#3433, 16#3434, 16#3435, 
      16#3436, 16#3437, 16#3438, 16#3439, 16#3441, 16#3442, 16#3443, 
      16#3444, 16#3445, 16#3446, 16#3530, 16#3531, 16#3532, 16#3533, 
      16#3534, 16#3535, 16#3536, 16#3537, 16#3538, 16#3539, 16#3541, 
      16#3542, 16#3543, 16#3544, 16#3545, 16#3546, 16#3630, 16#3631, 
      16#3632, 16#3633, 16#3634, 16#3635, 16#3636, 16#3637, 16#3638, 
      16#3639, 16#3641, 16#3642, 16#3643, 16#3644, 16#3645, 16#3646, 
      16#3730, 16#3731, 16#3732, 16#3733, 16#3734, 16#3735, 16#3736, 
      16#3737, 16#3738, 16#3739, 16#3741, 16#3742, 16#3743, 16#3744, 
      16#3745, 16#3746, 16#3830, 16#3831, 16#3832, 16#3833, 16#3834, 
      16#3835, 16#3836, 16#3837, 16#3838, 16#3839, 16#3841, 16#3842, 
      16#3843, 16#3844, 16#3845, 16#3846, 16#3930, 16#3931, 16#3932, 
      16#3933, 16#3934, 16#3935, 16#3936, 16#3937, 16#3938, 16#3939, 
      16#3941, 16#3942, 16#3943, 16#3944, 16#3945, 16#3946, 16#4130, 
      16#4131, 16#4132, 16#4133, 16#4134, 16#4135, 16#4136, 16#4137, 
      16#4138, 16#4139, 16#4141, 16#4142, 16#4143, 16#4144, 16#4145, 
      16#4146, 16#4230, 16#4231, 16#4232, 16#4233, 16#4234, 16#4235, 
      16#4236, 16#4237, 16#4238, 16#4239, 16#4241, 16#4242, 16#4243, 
      16#4244, 16#4245, 16#4246, 16#4330, 16#4331, 16#4332, 16#4333, 
      16#4334, 16#4335, 16#4336, 16#4337, 16#4338, 16#4339, 16#4341, 
      16#4342, 16#4343, 16#4344, 16#4345, 16#4346, 16#4430, 16#4431, 
      16#4432, 16#4433, 16#4434, 16#4435, 16#4436, 16#4437, 16#4438, 
      16#4439, 16#4441, 16#4442, 16#4443, 16#4444, 16#4445, 16#4446, 
      16#4530, 16#4531, 16#4532, 16#4533, 16#4534, 16#4535, 16#4536, 
      16#4537, 16#4538, 16#4539, 16#4541, 16#4542, 16#4543, 16#4544, 
      16#4545, 16#4546, 16#4630, 16#4631, 16#4632, 16#4633, 16#4634, 
      16#4635, 16#4636, 16#4637, 16#4638, 16#4639, 16#4641, 16#4642, 
      16#4643, 16#4644, 16#4645, 16#4646}). 

कौन सा मेरा नोटबुक i5 सीपीयू एम 520 पर प्रदर्शन 90MB/एस @ 2.40GHz जब 10 एमबी मात्रा पर परीक्षण किया। लेकिन अनुकूलन वहां चरम पर लाया गया था। 16 बिट लुकअप का उपयोग करते हुए यह 97 एमबी भी कर सकता है लेकिन यह पागल है और यहां पोस्ट करने में बहुत लंबा है।

4

आप कर सकते हैं: [एचडी (erlang: integer_to_list (निबल, 16)) || < < निबल: 4 >> < = बाइनरी]।

जो आपको बाइनरी के हेक्स अंकों वाले एक सूची (स्ट्रिंग) वापस करेगा। जबकि मुझे संदेह है कि इस ऑपरेशन की दक्षता आपके सिस्टम के रनटाइम पर कोई असर डालने वाला है, तो आप यह bin_to_hex फ़ंक्शन भी एक आईओलिस्ट लौटा सकते हैं जो निर्माण के लिए आसान है और आउटपुट के दौरान फ़्लैट किया जाएगा।

bin_to_hex(Bin) when is_binary(Bin) -> 
    JoinableLength = byte_size(Bin) - 1, 
    << Bytes:JoinableLength/binary, LastNibble1:4, LastNibble2:4 >> = Bin, 
    [ "<< ", 
     [ [ erlang:integer_to_list(Nibble1, 16), erlang:integer_to_list(Nibble2, 16), ", " ] 
     || << Nibble1:4, Nibble2:4 >> <= Bytes ], 
     erlang:integer_to_list(LastNibble1, 16), 
     erlang:integer_to_list(LastNibble2, 16), 
     " >>" ]. 

यह थोड़ा बदसूरत है, लेकिन एक बार द्विआधारी के माध्यम से चलाता है और उत्पादन सूची पार नहीं करता है (अन्यथा मैं का इस्तेमाल किया है था स्ट्रिंग: निम्नलिखित समारोह स्वरूपण उदाहरण आप दे दी है के साथ एक iolist रिटर्न में शामिल होने घुमावदार "," अनुक्रम प्राप्त करें)।

bin_to_hex(Bin) when is_binary(Bin) -> 
    "<< " ++ string:join([byte_to_hex(B) || <<B>> <= Bin ],", ") ++ " >>". 

byte_to_hex(<< N1:4, N2:4 >>) -> 
    [erlang:integer_to_list(N1, 16), erlang:integer_to_list(N2, 16)]. 
0
: इस समारोह कुछ प्रक्रिया के भीतरी पाश नहीं है, तो आप शायद कहीं अधिक स्पष्ट कोड की तरह कुछ तुच्छता से कम कुशल के साथ जाना चाहिए, लेकिन (मैं एक कठिन समय इस समारोह विश्वास अपने टोंटी होगा)
bin_to_hex_list(Bin) when is_binary(Bin) -> 
    lists:flatten([integer_to_list(X,16) || <<X>> <= Bin]). 
+2

यह किसी भी शून्य गद्दी नहीं करता है, तो परिणाम सही नहीं हैं। यदि बाइट के पहले 4 बिट 0 हैं तो यह केवल उस बाइट के लिए एक अंक उत्पन्न करेगा जब दो आवश्यक हों। –

6

@hairyhum में सुधार करने से

यह शून्य paddings << <<Y>> ||<<X:4>> <= Id, Y <- integer_to_list(X,16)>>

रिवर्स परिवर्तन <<<<Z>> || <<X:8,Y:8>> <= Id,Z <- [binary_to_integer(<<X,Y>>,16)]>>, %%hex to binary

का ख्याल रखता है
2

इसने कुछ समय के लिए कोई कार्रवाई नहीं देखी है, लेकिन सभी पूर्व समाधान अत्यधिक संकलित प्रतीत होते हैं।

[begin if N < 10 -> 48 + N; true -> 87 + N end end || <<N:4>> <= Bin] 

यदि आप चाहें, इसे थोड़ा विस्तार:

[begin 
    if 
     N < 10 -> 
      48 + N; % 48 = $0 
     true -> 
      87 + N % 87 = ($a - 10) 
    end 
end || <<N:4>> <= Bin] 
1

यहाँ एक और छोटी और तेज संस्करण है जो मैं का उपयोग करें: यहाँ, मेरे लिए, बहुत सरल लगता है

hexlify(Bin) when is_binary(Bin) -> 
    << <<(hex(H)),(hex(L))>> || <<H:4,L:4>> <= Bin >>. 

hex(C) when C < 10 -> $0 + C; 
hex(C) -> $a + C - 10. 
1

यदि आप एरलांग डिफ़ॉल्ट सूची तारों के बजाय बाइनरी स्ट्रिंग बनाना पसंद करते हैं, तो आप बाइनरी समझ वाक्यविन्यास का उपयोग कर सकते हैं, जैसा कि मैंने अपने sha1 जनरेटिंग कोड पर किया था:

1> << << if N >= 10 -> N -10 + $a; 
1>   true -> N  + $0 end >> 
1> || <<N:4>> <= crypto:hash(sha, "hello world") >>. 
<<"2aae6c35c94fcfb415dbe95f408b9ce91ee846ed">> 
अजगर binascii.b2a_hex में के रूप में एक ही

:

>>> binascii.b2a_hex(sha.new('hello world').digest()) 
'2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'