Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS will be completely phased out by mid-2025. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 6efc91c7 authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

Merge pull request #730 in VECTO/vecto-sim from...

Merge pull request #730 in VECTO/vecto-sim from ~EMQUARIMA/vecto-sim:feature/VECTO-873-add-digest-value-to-sumdata to develop

* commit 'f687d2ad':
  modify writing sum data to contain digest value
  adding testcase for digest value in sum-file
parents d34c109c f687d2ad
No related branches found
No related tags found
No related merge requests found
......@@ -91,7 +91,7 @@ namespace TUGraz.VectoCore.OutputData.FileIO
public void WriteSumData(DataTable data)
{
VectoCSVFile.Write(SumFileName, data, true);
VectoCSVFile.Write(SumFileName, data, true, true);
}
public string GetModDataFileName(string runName, string cycleName, string runSuffix)
......
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace TUGraz.VectoCore.Utils
{
public class DataIntegrityHelper
{
public static string ComputeDigestValue(string[] lines)
{
var hash = System.Convert.ToBase64String(GetHash(string.Join("\n", lines)));
return string.Format("SHA256: {0}", hash);
}
public static byte[] GetHash(string inputString)
{
HashAlgorithm algorithm = SHA256.Create();
return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}
}
}
......@@ -31,6 +31,7 @@
using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
......@@ -62,6 +63,7 @@ namespace TUGraz.VectoCore.Utils
private static readonly Regex HeaderFilter = new Regex(@"\[.*?\]|\<|\>", RegexOptions.Compiled);
private const string Delimiter = ",";
private const string Comment = "#";
private const string DigestValuePrefix = "#@";
/// <summary>
/// Reads a CSV file which is stored in Vecto-CSV-Format.
......@@ -175,10 +177,11 @@ namespace TUGraz.VectoCore.Utils
/// <param name="fileName">Path to the file.</param>
/// <param name="table">The Datatable.</param>
/// <param name="addVersionHeader"></param>
public static void Write(string fileName, DataTable table, bool addVersionHeader = false)
/// <param name="addDigest"></param>
public static void Write(string fileName, DataTable table, bool addVersionHeader = false, bool addDigest = false)
{
using (var sw = new StreamWriter(new FileStream(fileName, FileMode.Create), Encoding.UTF8)) {
Write(sw, table, addVersionHeader);
Write(sw, table, addVersionHeader, addDigest);
}
}
......@@ -190,21 +193,24 @@ namespace TUGraz.VectoCore.Utils
/// <param name="writer"></param>
/// <param name="table"></param>
/// <param name="addVersionHeader"></param>
public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false)
/// <param name="addDigest"></param>
public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false, bool addDigest = false)
{
if (writer == null) {
return;
}
var entries = new List<string>();
if (addVersionHeader) {
try {
writer.WriteLine("# VECTO {0} - {1}", VectoSimulationCore.VersionNumber,
DateTime.Now.ToString("dd.MM.yyyy HH:mm"));
entries.Add(string.Format("# VECTO {0} - {1}", VectoSimulationCore.VersionNumber,
DateTime.Now.ToString("dd.MM.yyyy HH:mm")));
} catch (Exception) {
writer.WriteLine("# VECTO {0} - {1}", "Unknown", DateTime.Now.ToString("dd.MM.yyyy HH:mm"));
entries.Add(string.Format("# VECTO {0} - {1}", "Unknown", DateTime.Now.ToString("dd.MM.yyyy HH:mm")));
}
}
var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName);
writer.WriteLine(string.Join(Delimiter, header));
entries.Add(string.Join(Delimiter, header));
var columnFormatter = new Func<ConvertedSI, string>[table.Columns.Count];
for (var i = 0; i < table.Columns.Count; i++) {
......@@ -221,21 +227,30 @@ namespace TUGraz.VectoCore.Utils
var formattedList = new string[items.Length];
for (var i = 0; i < items.Length; i++) {
if (items[i] is SI) {
formattedList[i] = columnFormatter[i]((SI)items[i]);
if (items[i] is SI) {
formattedList[i] = columnFormatter[i]((SI)items[i]);
} else if (items[i] is ConvertedSI) {
// todo mk-2017-10-02: maybe we also have to use decimals and showUnit from columnFormatter here?
formattedList[i] = columnFormatter[i]((ConvertedSI)items[i]);
} else {
formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]);
}
formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]);
}
// if a string contains a "," then it has to be contained in quotes in order to be correctly recognized in a CSV file.
// if a string contains a "," then it has to be contained in quotes in order to be correctly recognized in a CSV file.
if (formattedList[i].Contains(Delimiter)) {
formattedList[i] = string.Format("\"{0}\"", formattedList[i]);
}
}
writer.WriteLine(string.Join(Delimiter, formattedList));
entries.Add(string.Join(Delimiter, formattedList));
}
if (addDigest) {
var digest = DataIntegrityHelper.ComputeDigestValue(entries.Where(x => !x.StartsWith(DigestValuePrefix)).ToArray());
entries.Add(string.Format("{0} {1}", DigestValuePrefix, digest));
}
foreach (var entry in entries) {
writer.WriteLine(entry);
}
}
}
......
......@@ -222,6 +222,7 @@
<Compile Include="OutputData\XML\XMLDeclarationWriter.cs" />
<Compile Include="OutputData\XML\XMLEngineeringWriter.cs" />
<Compile Include="OutputData\XML\XMLManufacturerReport.cs" />
<Compile Include="Utils\DataIntegrityHelper.cs" />
<Compile Include="Utils\MeanShiftClustering.cs" />
<Compile Include="Utils\ProviderExtensions.cs" />
<Compile Include="Models\Declaration\AirDrag.cs" />
......
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using NUnit.Framework;
using NUnit.Framework.Internal;
using TUGraz.VectoCommon.Utils;
using TUGraz.VectoCore.Utils;
namespace TUGraz.VectoCore.Tests.Algorithms
{
[TestFixture]
public class CSVDigestValueTest
{
[TestCase]
public void TestDigestValueCreation()
{
var tbl = CreateDataTable(new[] { "t", "dt", "v" }, 5);
var str = new MemoryStream();
var writer = new StreamWriter(str);
VectoCSVFile.Write(writer, tbl, true, true);
writer.Flush();
str.Flush();
str.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(str);
var lines = new List<string>();
while (!reader.EndOfStream)
lines.Add(reader.ReadLine());
var last = lines.Last();
Assert.IsTrue(last.StartsWith("#@"), "Digest Identifier not found");
Assert.IsTrue(last.Contains("SHA256"), "Digest descriptor SHA256 not found");
}
[TestCase]
public void TestDigestValueValidation()
{
var tbl = CreateDataTable(new[] { "t", "dt", "v" }, 5);
var str = new MemoryStream();
var writer = new StreamWriter(str);
VectoCSVFile.Write(writer, tbl, true, true);
writer.Flush();
str.Flush();
str.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(str);
var lines = new List<string>();
while (!reader.EndOfStream)
lines.Add(reader.ReadLine());
var last = lines.Last();
Assert.IsTrue(last.StartsWith("#@"), "Digest Identifier not found");
Assert.IsTrue(last.Contains("SHA256"), "Digest descriptor SHA256 not found");
var otherLines = lines.Where(x => !x.StartsWith("#@")).ToArray();
var digest = DataIntegrityHelper.ComputeDigestValue(otherLines);
Assert.AreEqual(string.Format("#@ {0}", digest), last);
}
private static DataTable CreateDataTable(string[] cols, int numRows)
{
var tbl = new DataTable();
foreach (var col in cols) {
tbl.Columns.Add(col, typeof(double));
}
var rnd = new Randomizer(873);
for (var i = 0; i < numRows; i++) {
var row = tbl.NewRow();
foreach (var col in cols) {
row[col] = rnd.NextDouble(100);
}
tbl.Rows.Add(row);
}
return tbl;
}
}
}
......@@ -77,6 +77,7 @@
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="Algorithms\CSVDigestValueTest.cs" />
<Compile Include="Algorithms\MeanShiftClusteringTest.cs" />
<Compile Include="Dummy\EngineFLDTest.cs" />
<Compile Include="Exceptions\ExceptionTests.cs" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment