简体   繁体   English

如何逆转此C#解码方法的过程以创建编码方法?

[英]How to reverse the process of this C# Decode method to create an Encode method?

I would like to know how to reverse the process of the below DecodeBinaryBase64 so that I can have a matching Encode method. 我想知道如何反转下面的DecodeBinaryBase64的过程,以便可以使用匹配的Encode方法。 In short C# code that if given the output of this method it would return the same string that it took as input. 简而言之,C#代码提供了此方法的输出,它将返回与输入相同的字符串。

private static string DecodeBinaryBase64(string stringToDecode)
{
    StringBuilder builder = new StringBuilder();
    foreach (var b in Convert.FromBase64String(stringToDecode))
        builder.Append(string.Format("{0:X2}", b));
    return builder.ToString();
}

Here is an example of an encoded string and its decoded counterpart. 这是一个编码字符串及其解码对等的示例。 The result is a SHA1 hash for a file. 结果是文件的SHA1哈希。 The above method is an example of understanding how the decoding works to get to the right string. 上面的方法是理解解码如何工作以获取正确的字符串的示例。

ENCODED ENCODED

/KUGOuoESMWYuDb+BTMK1LaGe7k= / KUGOuoESMWYuDb + BTMK1LaGe7k =

DECODED DECODED

FCA5063AEA0448C598B836FE05330AD4B6867BB9 FCA5063AEA0448C598B836FE05330AD4B6867BB9

or 要么

0xFCA5063AEA0448C598B836FE05330AD4B6867BB9 0xFCA5063AEA0448C598B836FE05330AD4B6867BB9

Updated to reflect correct SHA1 value thanks to Porges and a fix for hex bug found by Dean 'codeka' Hardin. 由于使用了Porges和Dean'codeka'Hardin发现的六角错误修复程序,进行了更新以反映正确的SHA1值。

Implemented Solution 已实施的解决方案

Here is the the implementation I have now, it is from Porges post distilled down to two methods. 这是我现在拥有的实现,它是从Porges提炼到两种方法。

private static string EncodeFileDigestBase64(string digest)
{
    byte[] result = new byte[digest.Length / 2];

    for (int i = 0; i < digest.Length; i += 2)
        result[i / 2] = byte.Parse(digest.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);

    if (result.Length != 20)
        throw new ArgumentException("Not a valid SHA1 filedigest.");

    return Convert.ToBase64String(result);
}

private static string DecodeFileDigestBase64(string encodedDigest)
{
    byte[] base64bytes = Convert.FromBase64String(encodedDigest);
    return string.Join(string.Empty, base64bytes.Select(x => x.ToString("X2")));
}  

I don't believe it's physically possible. 我认为这在身体上是不可能的。 The problem is that string.Format("{0:X}", b) will return either 1 or 2 characters depending on whether the input byte is < 16 or not. 问题是string.Format("{0:X}", b)将返回1或2个字符,具体取决于输入字节是否小于16。 And you've got no way to know once the string has been joined together. 一旦将字符串连接在一起,您就无法知道。

If you can modify the DecodeBinaryBase64 method so that it always appends two character for each byte, ie by using string.Format("{0:X2}", b) then it will be possible by just taking the input string two characters at a time. 如果可以修改DecodeBinaryBase64方法,使其始终为每个字节追加两个字符,即使用string.Format("{0:X2}", b)则只需将输入字符串的两个字符取为a时间。

If you made that change to your DecodeBinaryBase64 , then you can use the following to convert back again: 如果您对DecodeBinaryBase64进行了更改,则可以使用以下内容再次转换回:

private static string DecodeBinaryBase64(string stringToDecode)
{
    StringBuilder builder = new StringBuilder();
    foreach (var b in Convert.FromBase64String(stringToDecode))
        builder.Append(string.Format("{0:X2}", b));
    return "0x" + builder.ToString();
}

private static string EncodeBinaryBase64(string stringToEncode)
{
    var binary = new List<byte>();
    for(int i = 2; i < stringToEncode.Length; i += 2)
    {
        string s = new string(new [] {stringToEncode[i], stringToEncode[i+1]});
        binary.Add(byte.Parse(s, NumberStyles.HexNumber));
    }
    return Convert.ToBase64String(binary.ToArray());
}

(Error checking and so on is missing, though) (但是,缺少错误检查等)

Well, you're going from Base-64 to an ASCII/UTF-8 string - and then outputting each character as a 2-digit hex value. 好吧,您将从Base-64转换为ASCII / UTF-8字符串-然后将每个字符输出为2位十六进制值。

I don't know of any way to automatically get that back. 我不知道有什么办法可以自动将其取回。 You may have to pull out two characters at a time, cast those as a "char", and use string.format() to turn those back into characters, maybe? 您可能必须一次提取两个字符,将其转换为“ char”,然后使用string.format()将其转换回字符,也许吗?

I've never seen the need to take hex output like that, and turn it back into a real string before. 我从未见过需要像这样十六进制输出,然后再将其转换为真实字符串的需要。 Hope that helps. 希望能有所帮助。

So I expanded my answer a bit: 所以我扩大了答案:

/** Here are the methods in question: **/
string Encode(string input)
{
    return SHA1ToBase64String(StringToBytes(input));
}

string Decode(string input)
{
    return BytesToString(Base64StringToSHA1(input));
}
/****/

string BytesToString(byte[] bytes)
{
    return string.Join("",bytes.Select(x => x.ToString("X2")));
}

byte[] StringToBytes(string input)
{
    var result = new byte[input.Length/2];

    for (var i = 0; i < input.Length; i+=2)
        result[i/2] = byte.Parse(input.Substring(i,2), System.Globalization.NumberStyles.HexNumber);

    return result;
}

string SHA1ToBase64String(byte[] hash)
{
    if (hash.Length != 20)
        throw new Exception("Not an SHA-1 hash.");

    return Convert.ToBase64String(hash);
}

byte[] Base64StringToSHA1(string input)
{
    return Convert.FromBase64String(input);
}

void Main() {

    var encoded = "/KUGOuoESMWYuDb+BTMK1LaGe7k=";

    var decoded = Decode(encoded);
    var reencoded = Encode(decoded);

    Console.WriteLine(encoded == reencoded); //True
    Console.WriteLine(decoded);
    // FCA5063AEA0448C598B836FE05330AD4B6867BB9
}

I guess the confusion in other comments was over whether you want to provide a left-inverse or a right-inverse. 我想其他评论的困惑在于您要提供左反转还是右反转。

That is do you want a function " f " that does: 那就是您想要一个执行以下功能的函数“ f ”:

f(Decode(x)) == x // "left inverse"

or: 要么:

Decode(f(x)) == x // "right inverse"

I assumed the latter, because you said (1st comment on other answer) that you wanted to be able to replicate Microsoft's encoding. 我认为是后者,因为您说过(对其他答案的第一个评论),您希望能够复制Microsoft的编码。 (And what Dean noted - your function wasn't providing reversible output.) :) (还有Dean所说的-您的功能没有提供可逆的输出。):)

Either way the above reimplements your version for correct output, so both functions are inverses of each other. 无论哪种方式,以上都会重新实现您的版本以实现正确的输出,因此这两个函数互为反函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM