将8位字符串转换为16字块的序列

时间:2016-09-04 13:42:48

标签: c# string encoding bytestring

我正在尝试使用密码哈希系统(使用chap令牌进行密码哈希)将PHP和Javascript页面转换为C#。所以我有示例页面来显示步骤结果:

var myapp = angular.module('myapp', ['ui']);

myapp.controller('controller', function ($scope) {
    $scope.list = ["one", "two", "thre", "four", "five", "six"];
});

angular.bootstrap(document, ['myapp']);

第一个警告显示字符串“M123456¼¢£i8£¬1”,所以在我的代码中我使用以下方式转换输入:

<?php
   $chapid='\115';
   $chapchallenge= '\274\013\242\243\236\226\151\224\070\023\243\207\252\061\016\254';
   $pass = '123456';
?>

<script type="text/javascript">
<!--
    alert('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>');
    alert(((str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
    alert((coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
    alert(binl2hex(coreMD5(str2binl('<?php echo $chapid; ?>' + '<?php echo $pass; ?>' + '<?php echo $chapchallenge; ?>'))));
//-->
</script>

/*
 * Convert an 8-bit character string to a sequence of 16-word blocks, stored
 * as an array, and append appropriate padding for MD4/5 calculation.
 * If any of the characters are >255, the high byte is silently ignored.
 */
function str2binl(str)
{
  var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks
  var blks = new Array(nblk * 16)
  for(var i = 0; i < nblk * 16; i++) blks[i] = 0
  for(var i = 0; i < str.length; i++)
    blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8)
  blks[i>>2] |= 0x80 << ((i%4) * 8)
  blks[nblk*16-2] = str.length * 8
  return blks
} 

接下来我必须将此字符串转换为字节(如public static string AsciiOctalToString(string ascii) { var list = ascii.Split('\\'); StringBuilder builder = new StringBuilder(); foreach (string octalPart in list.Where(x => x.Length > 0)) { int i = Convert.ToInt32(octalPart, 8); builder.Append(Convert.ToChar(i)); } return builder.ToString(); } ),但它的格式有些奇怪。我不明白如何'将8位字符串转换为16字块的序列'。预期结果(来自警报2)为str2binl(str)。我将{858927437, -1137298124, -1633443317, 949250454, -1433951469, -2136207823, 0, 0,0,0,0,0,0,0,184,0}翻译为:

str2binl(str)

但我的结果与预期不同。

你知道我在做错了什么吗?

我为JavaScript代码添加了括号:

public static int[] Str2Binl(string str)
{
    var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
    var blks = new int[nblk*16];

    for (var i = 0; i < str.Length; i++)
    {
        blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
        blks[i >> 2] |= 0x80 << (i%4*8);
    }
    blks[nblk*16 - 2] = str.Length*8;
    return blks;
}

但是行function str2binl(str) { var nblk = ((str.length + 8) >> 6) + 1 // number of 16-word blocks var blks = new Array(nblk * 16) for(var i = 0; i < nblk * 16; i++) { blks[i] = 0 } for(var i = 0; i < str.length; i++) { blks[i>>2] |= (str.charCodeAt(i) & 0xFF) << ((i%4) * 8) } blks[i>>2] |= 0x80 << ((i%4) * 8) blks[nblk*16-2] = str.length * 8 return blks } 也需要迭代器以及它在JS中的工作方式吗?

P.S。我不能在我的代码中使用这个JS库,我只需要哈希密码(它不是一个Web应用程序)。

1 个答案:

答案 0 :(得分:1)

似乎问题是你在for循环中放置了两行而不是只有一行。这有用吗?

public static int[] Str2Binl(string str)
{
    var nblk = ((str.Length + 8) >> 6) + 1; // number of 16-word blocks
    var blks = new int[nblk*16];

    int i;
    for (i = 0; i < str.Length; i++)
    {
        blks[i >> 2] |= (str[i] & 0xFF) << (i%4*8);
    }

    blks[i >> 2] |= 0x80 << (i%4*8);
    blks[nblk*16 - 2] = str.Length*8;
    return blks;
}

无论如何,正如我已经评论过的那样,如果你真的关心安全性,你不应该自己进行散列,甚至不要使用MD5或SHA,而应该使用PBKDF2。除非由于某种原因你需要保留当前的算法。

另一方面,您的AsciiOctalToString给了我不同的字符串:¼♂¢£??i?8‼£?ª1♫¬

顺便说一句,你可以避免使用where(尽管你可能不喜欢它):

var list = ascii.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);