Преобразование шестнадцатеричной строки JQ в ASCII - PullRequest
0 голосов
/ 26 августа 2018

Я заканчиваю в jq шестнадцатеричной строкой, которую я хочу преобразовать в ASCII, в jq.Выполнение этого вовне также подразумевает прохождение нескольких условий, что усложняет ситуацию и действительно замедляет решение.

Для ясности: это касается перевода строки, такого как:

"0x4162634b6c6d" -> "AbcKlm"

удаление"0x" легко (. [2:]), и я получил эквивалент в функции bash:

function h2a () 
{ 
    while read s; do
        n=0;
        while [[ "$n" -lt ${#s} ]]; do
            h="${s:$n:2}";
            printf "\x$h";
            n="$(($n+2))";
        done;
    done
}

, но я бы очень хотел сделать это в нативном jq.Я нашел Rosetta JQ , но не смог преобразовать.

Спасибо за помощь!

Редактировать: прогресс, найден как получить доступ к подстрокам Теперь, как мне конвертировать и повторять?

Ответы [ 3 ]

0 голосов
/ 27 августа 2018

Вы можете использовать такую ​​функцию:

def decode_hex:
    ("0123456789abcdef"|split("")|with_entries({key:.value, value:.key})) as $hex_map |
    def decode_nybble: $hex_map[ascii_downcase];
    def decode_byte: (.[0:1]|decode_nybble * 16) + (.[1:2]|decode_nybble);
    def pairs: range(0;length;2) as $i | .[$i:$i+2];
    [pairs|decode_byte] | implode;

Затем, чтобы использовать ее, удалите все не шестнадцатеричные символы и введите строку.

.[2:] | decode_hex

Интересные примечанияК моему удивлению, строки обрабатываются очень по-разному по сравнению с массивами.Вы не можете напрямую в них индексировать или выполнять над ними другие подобные операции с массивами.Вы можете увидеть, насколько неловко это может быть, посмотрев, как $hex_map и decode_byte были определены выше.

0 голосов
/ 12 сентября 2018

Если требуется эффективное решение, тогда ответьте на вопрос @ JeffMercado:

def decode_hex:
  def decode: if . < 58 then .-48 elif . < 91 then .-55 else .-87 end;
  def decode_byte: map(decode) | (.[0] * 16) + .[1];
  def pairs: explode | range(0;length;2) as $i | [.[$i], .[$i+1]];
  [pairs|decode_byte] | implode;
0 голосов
/ 26 августа 2018
$ cat q6.jq 
{ "b": 
   [(
     { "a": (split("")) }
     | .a[] 
     | gsub ("a"; "10"; "i") | gsub ("b"; "11"; "i") | gsub ("c"; "12"; "i") | gsub ("d"; "13"; "i") | gsub ("e"; "14"; "i") | gsub ("f"; "15"; "i")
    )
   ]
} 
| { "a": [ .b as $m | range(0; $m | length; 2) | { "q" : [ ($m[.]|tonumber),  ($m[(. + 1)]|tonumber) ] } ] } |
[ (.a[].q) as $b | (($b[0]) * 16) as $d | ($b[1]) as $e | ($d+$e) ] | implode

$ echo '"4162634b6c6d"' | jq -f q6.jq
"AbcKlm"
$

Да, я знаю, это ужасно, вдвое больше, чем функция bash, и она работает. Если вы можете улучшить: пожалуйста, покажите нам.

...