2016-07-29 4 views
0

일반 ASCII .txt 파일을 키/값 구성 파일로 사용하는 프로젝트에서 작업 중입니다. 성 = 퍼드 | | 사용자 아이디 = EFudd | 비밀번호 = 망가 | ConfigFile.txt에 대한 현재의 형식은C#에서 읽을 .txt 파일에 제어 문자 포함

FIRSTNAME = 엘머 같은 것입니다 날짜 =이은으로 읽기 쉬운 7/2천16분의 29

프로그램과 같은 코드 뭔가 KeyValuePairs와 사전 생성 : 그것은 처음 사용하여 별도의 문자열로 각각의 키/값을 분할

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]); 
     } 
     } 
    } 

를 '|' 구분 기호로 사용합니다. = EFudd

비밀

FIRSTNAME = 엘머

성 = 퍼드

의 UserId = foobar와

날짜이어서

= 7/2천16분의 29, 각각의 키/값 문자열에서 '='구분 기호의 키와 값을 분리하고, KeyValuePair를 만들고, 프로그램에서 나중의 조회를 위해 사전에 삽입합니다.

지금까지 그렇게 좋았습니다. 사용자는 구분 기호로 암호를 생성하지 않도록 지시받습니다. 그러나 암호를 파일에 포함하기 전에 암호를 암호화해야하며 암호화 루틴은 0x20에서 0x7F까지의 인쇄 가능한 문자를 생성 할 수 있습니다. 따라서 암호화 된 암호는 구분 기호 중 하나 또는 둘 모두로 끝날 수 있습니다. 나는 결국 'foobar'(또는 무엇이든)를 암호화 엔진에 의해 P # = = g %에 암호화되도록 끝낼 수 있습니다. 이것은 분할 함수가 제대로 작동하는 능력을 망칩니다.

그래서 메모장 .txt 파일에 입력 된 구분 기호를 변경하여 문자를 제어하여 '|' 구분 기호, 나는 0x1E (레코드 구분 기호)를 사용하고 '='기호를 0x1F (단위 구분 기호)로 바꿉니다.

이 문제는 C#에서 아무 문제없이 직접 이스케이프 처리하고 코딩 할 수 있지만 원래 .txt 디스크 파일을 수정하여 구분 기호로 단일 (인쇄 할 수없는) 문자로 올바르게 읽도록하려면 어떻게해야합니까?

+5

암호가 일반 텍스트입니까? 해시를 사용한 다음 이진 코드를 인코딩하려면 base64 또는 16 진수를 사용하십시오. –

+0

파일을 읽는 방법은 현재 파일을 읽는 것과 같습니다. 당신이 미쳐 가고 싶다면 원시 파일 스트림에 접근 할 수 있지만 SO에서 설명하는 데 더 많은 노력이 필요합니다. –

+0

나는 cleartext pwds를 상속 받았다. 나는 암호화된 텍스트가 설정 파일에 직접 입력되기 전에 디스크 또는 메모리에 일반 텍스트가 없도록하기 위해 그 위치에서 암호화하는 유틸리티를 작성했습니다. 응용 프로그램은 동일한 암호화를 사용하여 암호화를 사용하기 바로 전에 암호화를 해제합니다. – MiddleAgedMutantNinjaProgrammer

답변

0

가장 쉬운 답 :

가 ALT-numberpad 값 트릭을 사용하여 문자열에 특수 문자를 삽입합니다. 레코드 그룹 ALT-31 (▼)을 사용하여 키/값 쌍과 항목 그룹 ALT-30 (▲)의 끝을 구분하여 값에서 키를 구분하십시오. 문자열을 UTF-8로 저장하십시오. 구분 기호에 대한

코드 위쪽에 삼각형 아래로 넣어 같은 ALT-numberpad 트릭을 사용하여

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

입니다. 검은 삼각형을 절대로 편집하거나 제거하지 말고 그 의미를 설명하는 지침을 포함 시키십시오.

나는 옛날 DOS 시대로 거슬러 올라간다. 간단하고 구현하는데 5 분이 걸렸습니다. 기존 코드베이스가 실질적으로 변경 될 필요가 없습니다. 단 두 개의 분리 문자가 변경되었습니다.

+0

이 작업을 수행 할 수있는 다양한 기술을 개발 한 모든 사람들에게 감사드립니다. 그것이 그린 필드 프로그램이라면, 내가 다르게 할 많은 것들이 있습니다. 그러나 저는 90 년대 ASP (pre-AS.NET)와 Access 데이터베이스, 심지어는 IBM 360/370 메인 프레임 BAL (Basic Assembly Language)까지 모든 것을 지원하는 IT 부서에서 일합니다. 자신의 프로젝트를 자유롭게 할 때, 나는 학계에서 개발 된 테크닉을 일상적으로 사용합니다. 나는 SOAP/XML이 나오기 전에 REST/JSON을 사용 해왔다. 이 응용 프로그램은 kludge이지만 변경할 수 없으며 소유하지 않습니다. – MiddleAgedMutantNinjaProgrammer

0

그래서 일반 텍스트 대신 JSON과 같은 적절한 직렬화 형식을 사용합니다.

힘든 일을하는 도구가 있습니다.
내장 된 System.Web.Script.Serialization 네임 스페이스에는 사용할 수있는 도구가 있지만 Json.Net을 사용하는 것을 선호합니다. Visual Studio가 있으면 nuGet을 사용하여 설치할 수 있습니다 (그 이상의 도움이 필요하면 의견에 알려주십시오).

그러나 당신이 당신의 프로젝트에 추가하면,이

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); 

     } 
    } 
} 

및 ConfigFile 대처럼 뭔가를 할 수 있습니다.TXT는 당신이 더 사람이 읽을 수있는,

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

를 사용하려면이

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

모양을 그리고 당신은

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

"암호"다음에 코드를 작성합니다. 이것이 내가 이런 식으로해야만하는 이유입니다. 암호화 된 암호에 어떤 문자가 포함될 것인지 또는 편집 할 수있는 권한이 없습니다. 이스케이프 문자는 사용할 수 없습니다. 실제로 암호화 루틴은 일부 문자를 백 슬래시로 변환하여 다시 번역 할 수 있어야합니다. 암호는 암호화 기계에서 나온 암호이거나 암호 해독이 정확하지 않아야합니다. U R 이스케이프를 사용하여 암호화 된 pwd를 출력 - 암호 해독하지 않습니다. 암호화 된 pwd에 어떤 문자가 나타날지에 대한 제어권이 없습니다. – MiddleAgedMutantNinjaProgrammer

+0

@MiddleAgedMutantNinjaProgrammer 문자는 직렬화 될 때 이스케이프되지만, 비 직렬화시 정상이됩니다. 앱에서 비 직렬화 할 수 없다면 비밀번호 저장에 완전히 부적합합니다. – Zong

+0

@MiddleAgedMutantNinjaProgrammer 암호화 된 비밀번호에 포함될 문자를 제어 할 필요가 없습니다. 직렬화 프레임 워크를 사용하여 알아낼 수 있습니다. –

0

당신은 문자로 정수를 변환 할 수 있습니다거야 그러니 그냥 ...

,451,515,

...하지만 Base64로 쉽고 청소기 것 같은 암호를 인코딩 ...

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

... 참고 : 는 '나는 같으면 있도록 해시/암호화 된 데이터는 이러한 문자를 포함 할 가능성이있다 hases를 텍스트 파일에 덤프하십시오. 다음 클래스는 인쇄 할 수없는 문자와 정규 표현식 및 지원 암호를 사용하여 문자열 세그먼트를 추출

0

: × 00은 .. 0xFF의 이 클래스는 .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(); 

    } 

} 

는 사용 방법 :

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); 

샘플 출력 : 암호에는 인쇄 할 수없는 문자가 포함됩니다. 구분 및 기호

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