Task: OpenWebNet password




Go: package main

import (
    "fmt"
    "strconv"
)

func ownCalcPass(password, nonce string) uint32 {
    start := true
    num1 := uint32(0)
    num2 := num1
    i, _ := strconv.Atoi(password)
    pwd := uint32(i)
    for _, c := range nonce {
        if c != '0' {
            if start {
                num2 = pwd
            }
            start = false
        }
        switch c {
        case '1':
            num1 = (num2 & 0xFFFFFF80) >> 7
            num2 = num2 << 25
        case '2':
            num1 = (num2 & 0xFFFFFFF0) >> 4
            num2 = num2 << 28
        case '3':
            num1 = (num2 & 0xFFFFFFF8) >> 3
            num2 = num2 << 29
        case '4':
            num1 = num2 << 1
            num2 = num2 >> 31
        case '5':
            num1 = num2 << 5
            num2 = num2 >> 27
        case '6':
            num1 = num2 << 12
            num2 = num2 >> 20
        case '7':
            num3 := num2 & 0x0000FF00
            num4 := ((num2 & 0x000000FF) << 24) | ((num2 & 0x00FF0000) >> 16)
            num1 = num3 | num4
            num2 = (num2 & 0xFF000000) >> 8
        case '8':
            num1 = (num2&0x0000FFFF)<<16 | (num2 >> 24)
            num2 = (num2 & 0x00FF0000) >> 8
        case '9':
            num1 = ^num2
        default:
            num1 = num2
        }

        num1 &= 0xFFFFFFFF
        num2 &= 0xFFFFFFFF
        if c != '0' && c != '9' {
            num1 |= num2
        }
        num2 = num1
    }
    return num1
}

func testPasswordCalc(password, nonce string, expected uint32) {
    res := ownCalcPass(password, nonce)
    m := fmt.Sprintf("%s  %s  %-10d  %-10d", password, nonce, res, expected)
    if res == expected {
        fmt.Println("PASS", m)
    } else {
        fmt.Println("FAIL", m)
    }
}

func main() {
    testPasswordCalc("12345", "603356072", 25280520)
    testPasswordCalc("12345", "410501656", 119537670)
    testPasswordCalc("12345", "630292165", 4269684735)
}



PHP: function ownCalcPass($password, $nonce) {
    $msr = 0x7FFFFFFF;
    $m_1 = (int)0xFFFFFFFF;
    $m_8 = (int)0xFFFFFFF8;
    $m_16 = (int)0xFFFFFFF0;
    $m_128 = (int)0xFFFFFF80;
    $m_16777216 = (int)0xFF000000;
    $flag = True;
    $num1 = 0;
    $num2 = 0;

    foreach (str_split($nonce) as $c) {
        $num1 = $num1 & $m_1;
        $num2 = $num2 & $m_1;
        if ($c == '1') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 & $m_128;
            $num1 = $num1 >> 1;
            $num1 = $num1 & $msr;
            $num1 = $num1 >> 6;
            $num2 = $num2 << 25;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '2') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 & $m_16;
            $num1 = $num1 >> 1;
            $num1 = $num1 & $msr;
            $num1 = $num1 >> 3;
            $num2 = $num2 << 28;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '3') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 & $m_8;
            $num1 = $num1 >> 1;
            $num1 = $num1 & $msr;
            $num1 = $num1 >> 2;
            $num2 = $num2 << 29;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '4') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 << 1;
            $num2 = $num2 >> 1;
            $num2 = $num2 & $msr;
            $num2 = $num2 >> 30;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '5') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 << 5;
            $num2 = $num2 >> 1;
            $num2 = $num2 & $msr;
            $num2 = $num2 >> 26;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '6') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 << 12;
            $num2 = $num2 >> 1;
            $num2 = $num2 & $msr;
            $num2 = $num2 >> 19;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '7') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 & 0xFF00;
            $num1 = $num1 + (( $num2 & 0xFF ) << 24 );
            $num1 = $num1 + (( $num2 & 0xFF0000 ) >> 16 );
            $num2 = $num2 & $m_16777216;
            $num2 = $num2 >> 1;
            $num2 = $num2 & $msr;
            $num2 = $num2 >> 7;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '8') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = $num2 & 0xFFFF;
            $num1 = $num1 << 16;
            $numx = $num2 >> 1;
            $numx = $numx & $msr;
            $numx = $numx >> 23;
            $num1 = $num1 + $numx;
            $num2 = $num2 & 0xFF0000;
            $num2 = $num2 >> 1;
            $num2 = $num2 & $msr;
            $num2 = $num2 >> 7;
            $num1 = $num1 + $num2;
            $flag = False;
        } elseif ($c == '9') {
            $length = !$flag;
            if (!$length) {
                $num2 = $password;
            }
            $num1 = ~(int)$num2;
            $flag = False;
        } else {
            $num1 = $num2;
        }
        $num2 = $num1;
    }
    return sprintf('%u', $num1 & $m_1);
}