我想知道如何反转下面的DecodeBinaryBase64的过程,以便我可以使用匹配的Encode方法。简而言之,如果给出此方法的输出,它将返回与输入相同的字符串。
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();
}
以下是编码字符串及其解码对应字符的示例。结果是文件的SHA1哈希。上述方法是了解解码如何工作以获得正确字符串的示例。
ENCODED
/ KUGOuoESMWYuDb + BTMK1LaGe7k =
DECODED
FCA5063AEA0448C598B836FE05330AD4B6867BB9
或
0xFCA5063AEA0448C598B836FE05330AD4B6867BB9
更新以反映正确的SHA1值,这要归功于Porges和Dean'codeka'Dadin发现的六角虫修复。
已实施解决方案
这是我现在的实现,它是从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")));
}
答案 0 :(得分:3)
我不相信它在身体上是可能的。问题是string.Format("{0:X}", b)
将返回1或2个字符,具体取决于输入字节是否为&lt; 1。 16或不。一旦字符串连在一起,你就无法知道了。
如果你可以修改DecodeBinaryBase64
方法,使它总是为每个字节附加两个字符,即使用string.Format("{0:X2}", b)
,那么只需要一次输入两个字符就可以输入字符串。
如果您对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());
}
(但是缺少错误检查等等)
答案 1 :(得分:0)
好吧,你将从Base-64转到ASCII / UTF-8字符串 - 然后将每个字符输出为2位十六进制值。
我不知道有什么方法可以自动获得回复。您可能必须一次拉出两个字符,将它们转换为“char”,并使用string.format()将它们转换回字符,也许?
我从未见过像这样需要采用十六进制输出,并且之前将它变回真正的字符串。希望有所帮助。
答案 2 :(得分:0)
所以我稍微扩展了我的答案:
/** 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
}
我猜其他评论中的混淆是你想要提供左反或右反。
那你想要一个功能“f
”吗:
f(Decode(x)) == x // "left inverse"
或:
Decode(f(x)) == x // "right inverse"
我假设后者,因为你说(其他答案的第一条评论)你希望能够复制微软的编码。 (而Dean指出 - 你的功能并没有提供可逆输出。):)
无论哪种方式,上面重新实现了你的版本以获得正确的输出,因此两个函数都是相互反转的。