2016-07-29 3 views
0

Ich arbeite an einem Projekt, das eine einfache ASCII-TXT-Datei als Schlüssel/Wert-Konfigurationsdatei verwendet. Das aktuelle Format für ConfigFile.txt ist so etwas wieEinschließlich Steuerzeichen in einer TXT-Datei, die von C# gelesen werden kann

Vorname = Elmer | Name = Fudd | UserId = EFudd | Passwort = fubar | Date = 7/29/2016

Dies ist einfach, in der lesen Programm und ein Wörterbuch mit KeyValuePairs mit Code etwas schaffen wie:

using (FileStream fs = new FileStream("ConfigFile.txt", FileMode.Open)) 
    { 
     using (StreamReader sr = new StreamReader(fs)) 
     { 
     string fileText = sr.ReadToEnd(); 

     // Tokenize the entire file string into separate key=value strings. 
     string[] tokens = fileText.Split('|'); 

     // Iterate through all of the key=value strings, tokenize each one into a key=Value 
     // pair and add the key and value as separate strings into the dictionary. 
     foreach (string token in tokens) 
     { 
      string[] keyValuePair = token.Split('='); 
      configDict.Add(keyValuePair[0], keyValuePair[1]); 
     } 
     } 
    } 

Es spaltet zunächst jeden Schlüssel/Wert als separate Zeichenfolge aus mit dem ‚|‘ als Trennzeichen.

Vorname = Elmer

Name VZ = Fudd

UserId = EFudd

Passwort = foobar

Date = 7/29/2016

Dann wird für jeden Schlüssel/Wert string, trennt den Schlüssel und den Wert für das Trennzeichen "=", erstellt ein KeyValuePair und fügt es in ein Wörterbuch für spätere Suchvorgänge im Programm ein.

So weit so gut. Benutzer werden angewiesen, keine Kennwörter mit einem Trennzeichen zu erstellen. Allerdings muss ich nun das Passwort verschlüsseln, bevor es in die Datei eingefügt wird, und die Verschlüsselungsroutine kann jedes druckbare Zeichen von 0x20 bis 0x7F erzeugen. Ein verschlüsseltes Passwort kann also mit einem oder beiden der Begrenzer enden. Ich kann am Ende mit "Foobar" (oder was auch immer) durch die Verschlüsselungs-Engine in P # | = g% verschlüsselt werden. Dies beeinträchtigt die Fähigkeit der Split-Funktion, ordnungsgemäß zu arbeiten.

Also, ich möchte die Trennzeichen in die Notepad TXT-Datei geändert, um Zeichen zu steuern, so dass anstelle der '|' Trennzeichen, ich benutze 0x1E (Record Separator) und ersetze das '=' Zeichen mit 0x1F (Unit Separator).

Ich kann es entkommen und Code direkt in C# ohne Probleme, aber wie würde ich die ursprüngliche TXT-Datei ändern, so dass es die Trennzeichen als einzelne (nicht druckbare) Zeichen richtig lesen?

+5

Warum sind Passwörter Klartext? Verwenden Sie einen Hash und verwenden Sie dann base64 oder hex zum Kodieren der Binärdatei. –

+0

Wie Sie die Datei lesen, tun Sie es genau so, wie Sie gerade die Datei lesen. Wenn Sie verrückt werden möchten, können Sie auf den rohen Datei-Stream zugreifen, aber das erfordert mehr Aufwand, als sich auf SO zu konzentrieren. –

+0

Ich erbte Klartext pwds. Ich schrieb ein Dienstprogramm, um sie an Ort und Stelle zu verschlüsseln, bevor der verschlüsselte Text von Hand in die Konfigurationsdatei eingegeben wurde, so dass kein Klartext auf der Festplatte oder im Arbeitsspeicher vorhanden ist. Die Anwendung verwendet die gleiche Verschlüsselung, um sie vor ihrer Verwendung zu entschlüsseln. – MiddleAgedMutantNinjaProgrammer

Antwort

0

einfachste Antwort:

die Sonderzeichen in der Zeichenfolge Legen Sie die ALT-Nummernpad Wert Trick. Zeichnen Sie die Gruppe ALT-31 (▼), um das Ende eines Schlüssel/Wert-Paares zu begrenzen, und die Elementgruppe ALT-30 (▲), um den Schlüssel vom Wert abzugrenzen. Speichern Sie die Zeichenfolge als UTF-8.

-Code für Begrenzer ist

private static char tokenDelimiter = ('▲'); 
private static char keyValuePairDelimiter = ('▼'); 

den gleichen ALT-Nummernpad Trick in dem nach oben und unten Dreiecken zu setzen. Fügen Sie Anweisungen hinzu, dass die schwarzen Dreiecke NIE bearbeitet oder entfernt werden dürfen und erklären Sie ihre Bedeutung.

Es bringt mich zurück zu meinen alten DOS-Tagen. Einfach, und dauerte 5 Minuten zu implementieren - und es erfordert nicht, dass die vorhandene Codebasis wesentlich geändert werden - nur die zwei Trennzeichen geändert.

+0

Vielen Dank an alle, die sich eine Vielzahl von Techniken ausgedacht haben. Wenn es ein Greenfield-Programm wäre, gäbe es viele Dinge, die ich anders machen würde. Aber ich arbeite in einer IT-Abteilung, die noch alles aus den 90er Jahren ASP (preasP.NET) mit einer Access-Datenbank unterstützt, und sogar IBM 360/370 Mainframe BAL (Basic Assembly Language). Wenn ich frei bin, meine eigenen Projekte zu machen, verwende ich routinemäßig Techniken, die gerade in der Wissenschaft entwickelt werden. Ich benutze REST/JSON seit dem Erscheinen von SOAP/XML. Diese App ist ein Klud, aber ich darf es nicht ändern, ich besitze es nicht. – MiddleAgedMutantNinjaProgrammer

0

Also, anstatt einfachen Text wie das, was ich tun würde, verwenden Sie eine ordnungsgemäße Serialisierungsformat, wie JSON.

Es gibt Tools, die die harte Arbeit für Sie erledigen.
Der integrierte Namespace System.Web.Script.Serialization verfügt über einige Tools, die Sie verwenden können, aber ich bevorzuge Json.Net. Wenn Sie Visual Studio haben, können Sie es mit nuGet installieren (lassen Sie mich in den Kommentaren wissen, wenn Sie mehr Hilfe benötigen).

Aber sobald Sie es zu einem Projekt hinzufügen, können Sie so etwas wie diese

using System.Collections.Generic; 
using System.IO; 
using Newtonsoft.Json; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      var dict = new Dictionary<string, string>(); 

      dict.Add("FirstName", "Elmer"); 
      dict.Add("LastName", "Fudd"); 
      dict.Add("Password", @"\a\ansld\sb\b8d95nj"); 

      var json = JsonConvert.SerializeObject(dict); 

      File.WriteAllText("ConfigFile.txt, json); 

      var txt = File.ReadAllText("ConfigFile.txt"); 
      var newDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(txt); 

     } 
    } 
} 

und ConfigFile tun.txt aussehen wird diese

{"FirstName":"Elmer","LastName":"Fudd","Password":"\\a\\ansld\\sb\\b8d95nj"} 

Wenn Sie wollen, dass es mehr Menschen lesbare,

var json = JsonConvert.SerializeObject(dict, Formatting.Indented); 

verwenden und Sie werden

{ 
    "FirstName": "Elmer", 
    "LastName": "Fudd", 
    "Password": "\\a\\ansld\\sb\\b8d95nj" 
} 
+0

Es ist, was Sie nach "Passwort" programmieren: das ist, was mich dazu zwingt, es so zu machen. Ich habe keine Kontrolle darüber, welche Zeichen in dem verschlüsselten Passwort enthalten sein werden, noch kann ich es bearbeiten. Escape-Zeichen können nicht verwendet werden. In der Tat wird die Verschlüsselungsroutine einige Zeichen in umgekehrte Schrägstriche übersetzen und muss sie wieder zurückübersetzen können. Das Passwort muss genau sein, was aus dem Verschlüsselungsgerät kam oder es wird nicht richtig entschlüsselt. U R Ausgabe der verschlüsselten Pwd mit Escape - es wird nicht entschlüsseln. Ich habe KEINE Kontrolle darüber, welche Zeichen in der verschlüsselten PIN angezeigt werden. – MiddleAgedMutantNinjaProgrammer

+0

@MiddleAgedMutantNinjaProgrammer Die Zeichen werden beim Serialisieren maskiert, sind aber bei der Deserialisierung normal. Wenn Sie in der App nicht deserialisieren können, ist es zum Speichern von Kennwörtern völlig ungeeignet. – Zong

+0

@MiddleAgedMutantNinjaProgrammer Sie müssen nicht kontrollieren, welche Zeichen im verschlüsselten Passwort enthalten sein sollen. Verlassen Sie sich auf das Serialisierungs-Framework, um es für Sie herauszufinden. –

0

Sie ganze Zahlen Zeichen umwandeln bekommen also tun Sie das einfach ...

string[] tokens = fileText.Split((char)0x1e); 
// ... 
string[] keyValuePair = token.Split((char)0x1f); 

... aber kodieren Ihre Passwörter als base64 einfacher und saubere ...

wäre
string base64 = Convert.ToBase64String(passwordHash); 
byte[] passwordHash = Convert.FromBase64String(base64); 

... HINWEIS: es ist möglich, dass der Hashes/verschlüsselte Daten, die diese Zeichen enthalten, so I wouldn‘ t einfach die Hasen in die Textdatei ablegen.

0

Die folgende Klasse die Saitensegmente mit regulären Ausdrücken und Support Passwort mit nicht-druckbare Zeichen extrahieren: 0x00 .. 0xFF Die Klasse gehören Eigenschaften auf die Segmente der Konfiguration

Sie können laufen Demo Beispiel bei .NEt Fiddle

using System; 
using System.Text.RegularExpressions; 


class ConfigParser 
{ 
    public string Text { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string UserId { get; set; } 
    public string Password { get; set; } 
    public string Date { get; set; } 

    public ConfigParser(string text) 
    { 
     Text =text; 
     Parse(text); 
    } 


    private static string pattern = @" 
    ^FirstName=(?<firstname>\w+) \|   
    LastName=(?<lastname>\w+)  \|    
    UserId=(?<userid>\w+)   \|     
    Password=(?<pasword>.+)   
    Date=(?<date>.+)       
    $ 
    "; 

    private Regex regex = new Regex(pattern, 
      RegexOptions.Singleline 
      | RegexOptions.ExplicitCapture 
      | RegexOptions.CultureInvariant 
      | RegexOptions.IgnorePatternWhitespace 
      | RegexOptions.Compiled 
      ); 



    private void Parse(string text) 
    { 
     Console.WriteLine("text: {0}",text); 
     Match m = regex.Match(text); 
     FirstName = m.Groups["firstname"].ToString(); 
     LastName = m.Groups["lastname"].ToString(); 
     UserId = m.Groups["userid"].ToString(); 
     Password = m.Groups["pasword"].ToString(); 
     Date = m.Groups["date"].ToString(); 

    } 

} 

Wie verwenden:

var text ="your text here"; 
    var c = new ConfigParser(text);    

    you can access the properties of the class: FirstName, LastName,.... 

    Console.WriteLine("firstname: {0}", c.FirstName); 
    Console.WriteLine("lastname: {0}", c.LastName); 
    Console.WriteLine("UserId: {0}", c.UserId); 
    Console.WriteLine("Password: {0}", c.Password); 
    Console.WriteLine("date {0}", c.Date); 

Beispielausgabe: Das Kennwort enthält nicht druckbare Zeichen | Separator und Symbole

text: FirstName=Elmer|LastName=Fudd|UserId=EFudd|Password=fg%|uy|◄¶|hj↑khg|Date=7/29/2016 
firstname: Elmer 
lastname: Fudd 
UserId: EFudd 
Password: fg%|uy|◄¶|hj↑khg 
date: 7/29/2016 
Verwandte Themen