E
E
EminH2013-05-14 12:08:56
PHP
EminH, 2013-05-14 12:08:56

help translate from PHP to C#

Good afternoon, please help with the code in C #

there is such a function in PHP

 public function getCode($secret,$time = null) {
        
        if (!$time) {
            $time = floor(time() / 30);
        }
        $base32 = new FixedBitNotation(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', TRUE, TRUE);
        $secret = $base32->decode($secret);
        
        $time = pack("N", $time);
        $time = str_pad($time,8, chr(0), STR_PAD_LEFT);
        
        $hash = hash_hmac('sha1',$time,$secret,true);
        $offset = ord(substr($hash,-1));
        $offset = $offset & 0xF;
        
        $truncatedHash = self::hashToInt($hash, $offset) & 0x7FFFFFFF;
        $pinValue = str_pad($truncatedHash % self::$PIN_MODULO,6,"0",STR_PAD_LEFT);;
        return $pinValue;
    }
    
    protected  function hashToInt($bytes, $start) {
        $input = substr($bytes, $start, strlen($bytes) - $start);
        $val2 = unpack("N",substr($input,0,4));
        return $val2[1];
    }


I dug up its analogue in C # (.Net) on the network, but the results are different

public static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

public static string GetPassword(string secret )
{
    long counter = (long)((DateTime.UtcNow - UNIX_EPOCH).TotalSeconds ) / 30;

    return GeneratePassword(secret, counter);
}
     public static string GeneratePassword(string secret, long iterationNumber)
{
int digits = 6;
    byte[] counter = BitConverter.GetBytes(iterationNumber);

    if (BitConverter.IsLittleEndian)
        Array.Reverse(counter);

    byte[] key = Encoding.ASCII.GetBytes(secret);

    HMACSHA1 hmac = new HMACSHA1(key, true);

    byte[] hash = hmac.ComputeHash(counter);

    int offset = hash[hash.Length - 1] & 0xf;

    int binary =
        ((hash[offset] & 0x7f) << 24)
        | ((hash[offset + 1] & 0xff) << 16)
        | ((hash[offset + 2] & 0xff) << 8)
        | (hash[offset + 3] & 0xff);

    int password = binary % (int)Math.Pow(10, digits); // 6 digits

    return password.ToString(new string('0', digits));
}


help me find the error,

thanks

Answer the question

In order to leave comments, you need to log in

3 answer(s)
P
Puma Thailand, 2013-05-14
@EminH

And what's stopping you from turning on the debugger and walking through the code, there are 20 lines of it here.
Questions like this always surprise me.

F
Fr3nzy, 2013-05-14
@Fr3nzy

Do you use the same encoding in C# and PHP? In other words, you should, for example, use UTF-8 both there and there.

E
EminH, 2013-05-14
@EminH

Fr3nzy,
You have the same encoding used in C # and PHP

All arguments and results are only Latin and numbers ... namely, only this character set: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question