Dandraka.Zoro
2.1.3
See the version list below for details.
dotnet add package Dandraka.Zoro --version 2.1.3
NuGet\Install-Package Dandraka.Zoro -Version 2.1.3
<PackageReference Include="Dandraka.Zoro" Version="2.1.3" />
paket add Dandraka.Zoro --version 2.1.3
#r "nuget: Dandraka.Zoro, 2.1.3"
// Install Dandraka.Zoro as a Cake Addin #addin nuget:?package=Dandraka.Zoro&version=2.1.3 // Install Dandraka.Zoro as a Cake Tool #tool nuget:?package=Dandraka.Zoro&version=2.1.3
Zoro - The masked avenger
Zoro is a data masking and anonymization utility. It fetches data from a database, a JSON or a CSV file, and either creates a JSON file, a CSV file or runs SQL statements with the masked data.
It can be used as a command line program or as a dotnet standard 2.1 library. To run the command line program, simply copy the tools
dir from the Nuget package. Windows and Linux versions, both 64-bit, are available.
Usage:
As a command line utility:
[Win] zoro.exe path_to_config_file
E.g. zoro.exe c:\temp\mask.xml
[Linux] ./zoro path_to_config_file
E.g. zoro /home/jim/data/mask.xml
As a library
// === either read config from file ===
var configFromFile = Zoro.Processor.MaskConfig.ReadConfig("c:\temp\mask.xml");
// === or create in code ===
var config = new Zoro.Processor.MaskConfig()
{
ConnectionString = "Server=myDbServer;Database=myDb;User Id=myUser;Password=myPassword;",
ConnectionType = "System.Data.SqlClient",
DataSource = DataSource.Database,
DataDestination = DataDestination.CsvFile,
SqlSelect = "SELECT * FROM testdata",
OutputFile = Path.Combine(utility.TestInstanceDir, "maskeddata_db_02.csv")
};
config.FieldMasks.Add(new FieldMask() { FieldName = "name", MaskType = MaskType.Similar });
config.FieldMasks.Add(new FieldMask() { FieldName = "iban", MaskType = MaskType.Asterisk });
config.FieldMasks.Add(new FieldMask() { FieldName = "country", MaskType = MaskType.None });
config.FieldMasks.Add(new FieldMask() { FieldName = "address", MaskType = MaskType.List });
config.FieldMasks[3].ListOfPossibleReplacements.Add(new Replacement()
{ Selector = "country=CH", ReplacementList="Bahnhofstrasse 41,Hauptstrasse 8,Berggasse 4" });
config.FieldMasks[3].ListOfPossibleReplacements.Add(new Replacement()
{ Selector = "country=GR", ReplacementList="Evangelistrias 22,Thessalias 47,Eparhiaki Odos Lefkogion 6" });
// fallback when nothing matches; MUST be the last one
config.FieldMasks[3].ListOfPossibleReplacements.Add(new Replacement()
{ Selector = "", ReplacementList="Main Street 9,Fifth Avenue 104,Ranch rd. 1" });
// === with your config, call the masking method ===
var masker = new Zoro.Processor.DataMasking(config);
masker.Mask();
Sample config file:
<?xml version="1.0"?>
<MaskConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FieldMasks>
<FieldMask>
<FieldName>Name</FieldName>
<MaskType>Similar</MaskType>
</FieldMask>
<FieldMask>
<FieldName>BankAccount</FieldName>
<MaskType>Asterisk</MaskType>
</FieldMask>
</FieldMasks>
<InputFile>C:\temp\Zorotests\data.csv</InputFile>
<OutputFile>C:\temp\Zorotests\maskeddata.csv</OutputFile>
<Delimiter>;</Delimiter>
</MaskConfig>
The above config file can process for example the following CSV:
ID;Name;BankAccount
1;KM-elektronik;CH9880808007645910141
2;Cretaneshop;GR4701102050000020547061026
3;VELOPLUSs.r.l;IT36K0890150920000000550061
4;natuurhulpcentrum.be;BE79235040722733
and the result will be something like the following:
ID;Name;BankAccount
1;RJ-egitrjitiz;*********************
2;Lqebuhuzfic;***************************
3;NKWNQWWBg.g.q;***************************
4;botaahjazlvojknub.qi;****************
A more complete sample of a config file is the following:
<?xml version="1.0"?>
<MaskConfig xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FieldMasks>
<FieldMask>
<FieldName>ID</FieldName>
<MaskType>None</MaskType>
</FieldMask>
<FieldMask>
<FieldName>CountryISOCode</FieldName>
<MaskType>None</MaskType>
</FieldMask>
<FieldMask>
<FieldName>MainPhone</FieldName>
<MaskType>Similar</MaskType>
<RegExMatch>^(\+\d\d)?(.*)$</RegExMatch>
<RegExGroupToReplace>2</RegExGroupToReplace>
</FieldMask>
<FieldMask>
<FieldName>Street</FieldName>
<MaskType>List</MaskType>
<ListOfPossibleReplacements>
<Replacement Selector="Country=Netherlands" List="Bergselaan,Schieweg,Nootdorpstraat,Nolensstraat" />
<Replacement Selector="Country=Switzerland" List="Bahnhofstrasse,Clarahofweg,Sperrstrasse,Erlenstrasse" />
<Replacement Selector="Country=Liechtenstein" List="Lettstrasse,Bangarten,Beckagässli,Haldenweg" />
<Replacement Selector="Country=Germany" List="Bahnhofstraße,Freigaße,Hauptstraße" />
<Replacement Selector="Country=Belgium" List="Rue d'Argent,Rue d'Assaut,Rue de l'Ecuyer,Rue du Persil" />
<Replacement Selector="Country=Austria" List="Miesbachgasse,Kleine Pfarrgasse,Heinestraße" />
<Replacement Selector="Country=France" List="Rue Nationale,Boulevard Vauban,Rue des Stations,Boulevard de la Liberté" />
<Replacement Selector="" List="Bedford Gardens,Sheffield Terrace,Kensington Palace Gardens" />
</ListOfPossibleReplacements>
</FieldMask>
<FieldMask>
<FieldName>City</FieldName>
<MaskType>Query</MaskType>
<QueryReplacement SelectorField="CountryISOCode" GroupField="countrycode" ValueField="cityname" Query="SELECT cityname, countrycode FROM cities" />
</FieldMask>
</FieldMasks>
<DataSource>Database</DataSource>
<DataDestination>Database</DataDestination>
<ConnectionString>Server=DBSRV1;Database=appdb;Trusted_Connection=yes;</ConnectionString>
<ConnectionType>System.Data.SqlClient</ConnectionType>
<SqlSelect>SELECT * FROM customers</SqlSelect>
<SqlCommand>INSERT INTO customers_anonymous (ID, MainPhone, Street) VALUES ($ID, $MainPhone, $Street)</SqlCommand>
</MaskConfig>
If using a database to write data (DataDestination=Database), the number of parameters in SqlCommand ($field) must match the number of FieldMasks.
Note:
Although not required by the license, the author kindly asks that you share any improvements you made.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- GenericParsing (>= 1.2.2)
- System.Data.SqlClient (>= 4.8.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.3.4 | 316 | 6/3/2024 |
2.3.3 | 242 | 5/31/2024 |
2.3.2 | 305 | 5/31/2024 |
2.3.1 | 304 | 5/30/2024 |
2.3.0 | 318 | 5/29/2024 |
2.2.1 | 286 | 4/29/2024 |
2.1.4 | 288 | 4/25/2024 |
2.1.3 | 264 | 4/23/2024 |
2.1.2 | 261 | 4/23/2024 |
2.0.3 | 269 | 2/28/2024 |
2.0.1 | 737 | 1/4/2023 |
2.0.0 | 874 | 12/9/2021 |
1.0.7 | 520 | 11/28/2021 |
1.0.2 | 359 | 9/24/2021 |
Added basic JSON support. Addresses SQL Data Provider Security Feature Bypass Vulnerability CVE-2024-0056 on Microsoft.Data.SqlClient and System.Data.SqlClient