私はLinux(シェル)を初めて使用します。 Linuxシェルスクリプトを使用してxmlファイルのbase64テキストをデコードする必要があります。 Encoding = "base64"属性を使用してそのタグの値をデコードするLinuxシェルスクリプトを作成するのに役立ちますか?私のファイル構造は次のとおりです。
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">aGVsbG8gd29ybGQ= </value>
<value encoding="base64">
Q049RmxvcHB5IC0g0LTQvtGB0YLRg9C/INC30LDQutGA0YvRgixPVT1EZXZpY2UgQ29udHJv
bCxPVT1Hcm91cHMsT1U90JHQkNCd0JosREM9aHEsREM9YmM=
</value>
<value encoding="base64">
Q049VVNCLdC00LjRgdC60LggLSDRgtC+0LvRjNC60L4g0YfRgtC10L3QuNC1LE9VPURldmlj
ZSBDb250cm9sLE9VPUdyb3VwcyxPVT3QkdCQ0J3QmixEQz1ocSxEQz1iYw==
</value>
</attr>
</entry>
</directory-entries>
希望の出力は
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">Hello world </value>
<value encoding="base64"> decoded </value>
<value encoding="base64"> decoded </value>
</attr>
</entry>
</directory-entries>
Active DirectoryでXMLを生成するためにldapsearchを使用しています。ファイルのインポートに使用するスクリプトは次のとおりです。
ldapsearch -h host -p 389 -D "CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc" -w password -s sub -B -E UTF-8 -X "(&(objectClass=organizationalPerson)(CN=*))" employeeID memberof > ldap_logins.xml
xmlファイルの生成中にテキストをデコードすることが可能かどうかわかりません。よろしくお願いします!
答え1
私がいつも何をしているのか話しましょう。 XML の解析に正規表現を使用しないでください。これは悪いニュースです。 XMLはさまざまな形式で提供されます。これは、意味的に同じXMLが特定の正規表現に一致するか一致しないことを意味します。改行、単項タグなどのような単純なものです。
これは、上流のデータフローの完全に有効な変更があるため、ある日未知の理由で壊れる可能性がある脆弱なコードを生成することを意味します。
解析のためあなたのXMLの使用をお勧めperl
し、かなり良いです。XML::Twig
基準寸法。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
use MIME::Base64;
#we take a "value" element, check it for an "encoding=base64" and if it is
#we rewrite the content and delete that attribute in the XML.
sub decode_value {
my ( $twig, $value ) = @_;
if ( $value->att('encoding')
and $value->att('encoding') eq "base64" )
{
my $decoded_text = decode_base64( $value->text );
if ( $decoded_text =~ m/[^\s\d\w\=\-\,\.]/ ) {
$decoded_text = "decoded";
}
$value->set_text($decoded_text);
$value -> del_att('encoding');
}
}
#twig handlers 'fires' a piece of code each time you hit a 'value' element.
#it passes this piece of code that chunk of XML to handle, which means
#you can do things like dynamic XML rewrites
#pretty print controls output XML rendering - there's a variety of options
#check the manpage.
my $twig = XML::Twig->new(
pretty_print => "indented",
twig_handlers => { 'value' => \&decode_value, }
);
$twig->parsefile('your_xml_file');
$twig->print;
これにより、以下が提供されます。
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">hello world</value>
<value encoding="base64">decoded</value>
<value encoding="base64">decoded</value>
</attr>
</entry>
</directory-entries>
次のように変換することもできます$decoded_text
。
$decoded_text =~ s/[^\s\d\w=,-. ]+/_/g;
(URI::Escape
ここにあるモジュールはテキストURLスタイルを「パーセントエンコード」するので、見てみる価値があります。)
これにより、以下が提供されます。
<value encoding="base64">CN=Floppy - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>
<value encoding="base64">CN=USB-_ - _ _,OU=Device Control,OU=Groups,OU=_,DC=hq,DC=bc</value>
Net::LDAP
ただし、用途を使用すると要件が満たされる可能性があります。
#!/usr/bin/perl
use strict;
use warnings;
use Net::LDAP;
my $ldap = Net::LDAP->new('host');
my $result = $ldap->bind(
'CN=informatica,OU=Accounts for System Purposes,OU=System Accounts,DC=hq,DC=bc',
'password'
);
if ( $result->code ) { die "Error connecting to LDAP server"; }
my $ldap_search = $ldap->search(
base => 'DC=hq,DC=bc',
scope => 'subtree',
filter => '(&(objectClass=organizationalPerson)(CN=*))',
attrs => [ 'employeeID', 'memberOf' ],
);
foreach my $entry ( $ldap_search->entries ) {
print "dn:\t", $entry->dn(), "\n";
foreach my $attr ( $entry->attributes ) {
print "$attr:";
foreach my $value ( $entry->get_value($attr) ) {
next unless defined $value;
if ( $value =~ m/[^\s\d\w,-=+@\'.()]/ ) { $value = "binary_data" }
chomp($value);
print "\t$value\n";
}
}
}
答え2
コンパクトスクリプト
xmlがにあるとし、file.xml
次のようにします。
sed -r 's/("base64">)([[:graph:]]+)/\1'"`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`"'/g' file.xml
以下は、操作を実行する単純な正規表現です。分解して説明します。
崩れる
まず、grepを使用してBase64文字列を選択してデコードします。
grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d
変数に保存できます。
baseString=`grep -oP '"base64">\K[[:graph:]]+' file.xml | base64 -d`
次に、sed
base64を変数に格納されているデコードされた文字列に置き換えます。
sed -r 's/("base64">)([[:graph:]]+)/\1'"$baseString"'/g' file.xml
答え3
を使用するのが正解ですxmlstarlet
。これはXMLの解析と編集のためのツールです。まず、このパッケージをシステムにインストールします。 Debian ベースのシステムを使用している場合は、次の手順を実行します。
sudo apt-get install xmlstarlet
今、
- まず、base64でエンコードされた文字列の値を読み取ります。
- その後、この文字列をデコードします。
- 次に、対応するタグ値を変更します。
完全なスクリプトは次のとおりです。
#!/bin/bash
for i in $(seq 3)
do
#Find the string and decoded it and save it in a variable
decodedString=`xmlstarlet sel -t -v "/directory-entries/entry/attr/value[@encoding='base64'][$i]" file.xml | tr -d \r\n[:space:] | base64 -d`
#Now modify the xml document
xmlstarlet ed -L -u "/directory-entries/entry/attr/value[@encoding='base64'][$i]" -v "$decodedString" file.xml
done
私はこれを3ループ実行しました。必要な数の要素でこれを行うことができます。
答え4
xq
以下で使用https://kislyuk.github.io/yq/:
xq -x '( .. | select(type == "object" and ."@encoding" == "base64")."#text" )
|= ( gsub("\n"; "") | @base64d )' file.xml
これは文書全体を再帰的に検索し、値が..の属性をencoding
持つbase64
ノードを見つけます。これらの各ノードのノードの値を取得し、すべての改行を削除し(使用gsub()
)、演算子を使用してbase64文字列をデコードします@base64d
。デコードされた値は元のBase64データを置き換えます。
問題の文書が与えられた場合、出力は次のようになります。
<directory-entries>
<entry dn="ads">
<attr name="memberof">
<value>CN=VPN-employee</value>
<value encoding="base64">hello world</value>
<value encoding="base64">CN=Floppy - доступ закрыт,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
<value encoding="base64">CN=USB-диски - только чтение,OU=Device Control,OU=Groups,OU=БАНК,DC=hq,DC=bc</value>
</attr>
</entry>
</directory-entries>
このツールには、「内部」編集を実行するxq
オプションもあります。-i
--in-place