OpenWebNet password: Difference between revisions

From Rosetta Code
Content added Content deleted
(+ D entry)
(Updated D entry)
Line 22: Line 22:
pure nothrow @safe @nogc
pure nothrow @safe @nogc
in {
in {
//assert(nonce.all!isDigit); //** non-@nogc.
assert(nonce.representation.all!isDigit);
foreach (immutable char c; nonce)
assert(c.isDigit);
} body {
} body {
enum ulong m_1 = 0xFFFFFFFFUL;
enum ulong m_1 = 0x_FFFF_FFFF_UL;
enum ulong m_8 = 0xFFFFFFF8UL;
enum ulong m_8 = 0x_FFFF_FFF8_UL;
enum ulong m_16 = 0xFFFFFFF0UL;
enum ulong m_16 = 0x_FFFF_FFF0_UL;
enum ulong m_128 = 0xFFFFFF80UL;
enum ulong m_128 = 0x_FFFF_FF80_UL;
enum ulong m_16777216 = 0XFF000000UL;
enum ulong m_16777216 = 0X_FF00_0000_UL;


auto flag = true;
auto flag = true;
Line 133: Line 131:
void ownTestCalcPass(in string sPassword, in string nonce, in ulong expected)
void ownTestCalcPass(in string sPassword, in string nonce, in ulong expected)
in {
in {
assert(sPassword.all!isDigit);
assert(sPassword.representation.all!isDigit);
assert(nonce.all!isDigit);
assert(nonce.representation.all!isDigit);
} body {
} body {
immutable password = sPassword.to!ulong;
immutable password = sPassword.to!ulong;

Revision as of 14:28, 1 November 2014

OpenWebNet password is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Calculate the password requested by ethernet gateways from the Legrand / Bticino MyHome OpenWebNet home automation system when the user's ip address is not in the gateway's whitelist

Note: Factory default password is '12345'. Changing it is highly recommended !

conversation goes as follows

← *#*1##
→ *99*0##
← *#603356072##

at which point a password should be sent back, calculated from the "password open" that is set in the gateway, and the nonce that was just sent

→ *#25280520##
← *#*1##

D

Translation of: Python

<lang d>import std.stdio, std.string, std.conv, std.ascii, std.algorithm;

ulong ownCalcPass(in ulong password, in string nonce) pure nothrow @safe @nogc in {

   assert(nonce.representation.all!isDigit);

} body {

   enum ulong m_1        = 0x_FFFF_FFFF_UL;
   enum ulong m_8        = 0x_FFFF_FFF8_UL;
   enum ulong m_16       = 0x_FFFF_FFF0_UL;
   enum ulong m_128      = 0x_FFFF_FF80_UL;
   enum ulong m_16777216 = 0X_FF00_0000_UL;
   auto flag = true;
   ulong num1 = 0, num2 = 0;
   foreach (immutable char c; nonce) {
       num1 &= m_1;
       num2 &= m_1;
       switch (c) {
           case '0':
               num1 = num2;
               break;
           case '1':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 & m_128;
               num1 = num1 >> 7;
               num2 = num2 << 25;
               num1 = num1 + num2;
               break;
           case '2':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 & m_16;
               num1 = num1 >> 4;
               num2 = num2 << 28;
               num1 = num1 + num2;
               break;
           case '3':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 & m_8;
               num1 = num1 >> 3;
               num2 = num2 << 29;
               num1 = num1 + num2;
               break;
           case '4':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 << 1;
               num2 = num2 >> 31;
               num1 = num1 + num2;
               break;
           case '5':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 << 5;
               num2 = num2 >> 27;
               num1 = num1 + num2;
               break;
           case '6':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 << 12;
               num2 = num2 >> 20;
               num1 = num1 + num2;
               break;
           case '7':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 & 0xFF00UL;
               num1 = num1 + ((num2 & 0xFFUL) << 24);
               num1 = num1 + ((num2 & 0xFF0000UL) >> 16);
               num2 = (num2 & m_16777216) >> 8;
               num1 = num1 + num2;
               break;
           case '8':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = num2 & 0xFFFFUL;
               num1 = num1 << 16;
               num1 = num1 + (num2 >> 24);
               num2 = num2 & 0xFF0000UL;
               num2 = num2 >> 8;
               num1 = num1 + num2;
               break;
           case '9':
               if (flag)
                   num2 = password;
               flag = false;
               num1 = ~num2;
               break;
           default: // Impossible if contracts are active.
               assert(0, "Non-digit in nonce");
       }
       num2 = num1;
   }
   return num1 & m_1;

}

void ownTestCalcPass(in string sPassword, in string nonce, in ulong expected) in {

   assert(sPassword.representation.all!isDigit);
   assert(nonce.representation.all!isDigit);

} body {

   immutable password = sPassword.to!ulong;
   immutable res = ownCalcPass(password, nonce);
   immutable m = format("%d %s %d %d", password, nonce, res, expected);
   writeln((res == expected) ? "PASS " : "FAIL ", m);

}

void main() {

   ownTestCalcPass("12345", "603356072", 25280520UL);
   ownTestCalcPass("12345", "410501656", 119537670UL);

}</lang>

Output:
PASS 12345 603356072 25280520 25280520
PASS 12345 410501656 119537670 119537670

JavaScript

<lang javascript> function calcPass (pass, nonce) { var flag = true; var num1 = 0x0; var num2 = 0x0; var password = parseInt(pass, 10);

for (var c in nonce) { c = nonce[c]; if (c!='0') { if (flag) num2 = password; flag = false; } switch (c) { case '1': num1 = num2 & 0xFFFFFF80; num1 = num1 >>> 7; num2 = num2 << 25; num1 = num1 + num2; break; case '2': num1 = num2 & 0xFFFFFFF0; num1 = num1 >>> 4; num2 = num2 << 28; num1 = num1 + num2; break; case '3': num1 = num2 & 0xFFFFFFF8; num1 = num1 >>> 3; num2 = num2 << 29; num1 = num1 + num2; break; case '4': num1 = num2 << 1; num2 = num2 >>> 31; num1 = num1 + num2; break; case '5': num1 = num2 << 5; num2 = num2 >>> 27; num1 = num1 + num2; break; case '6': num1 = num2 << 12; num2 = num2 >>> 20; num1 = num1 + num2; break; case '7': num1 = num2 & 0x0000FF00; num1 = num1 + (( num2 & 0x000000FF ) << 24 ); num1 = num1 + (( num2 & 0x00FF0000 ) >>> 16 ); num2 = ( num2 & 0xFF000000 ) >>> 8; num1 = num1 + num2; break; case '8': num1 = num2 & 0x0000FFFF; num1 = num1 << 16; num1 = num1 + ( num2 >>> 24 ); num2 = num2 & 0x00FF0000; num2 = num2 >>> 8; num1 = num1 + num2; break; case '9': num1 = ~num2; break; case '0': num1 = num2; break; } num2 = num1; } return (num1 >>> 0).toString(); }

exports.calcPass = calcPass;

console.log ('openpass initialization'); function testCalcPass (pass, nonce, expected) { var res = calcPass (pass, nonce); var m = pass + ' ' + nonce + ' ' + res + ' ' + expected; if (res == parseInt(expected, 10)) console.log ('PASS '+m); else console.log ('FAIL '+m); }

testCalcPass ('12345', '603356072', '25280520'); testCalcPass ('12345', '410501656', '119537670'); testCalcPass ('12345', '630292165', '4269684735'); testCalcPass ('12345', '523781130', '537331200'); </lang>

Python

<lang python>#!/usr/bin/env python

  1. -*- coding: utf-8 -*-

def ownCalcPass (password, nonce) :

   m_1 = 0xFFFFFFFFL
   m_8 = 0xFFFFFFF8L
   m_16 = 0xFFFFFFF0L
   m_128 = 0xFFFFFF80L
   m_16777216 = 0XFF000000L
   flag = True
   num1 = 0L
   num2 = 0L
   password = long(password)
   for c in nonce :
       num1 = num1 & m_1
       num2 = num2 & m_1
       if c == '1':
           length = not flag
           if not length :
               num2 = password
           num1 = num2 & m_128
           num1 = num1 >> 7
           num2 = num2 << 25
           num1 = num1 + num2
           flag = False
       elif c == '2':
           length = not flag
           if not length :
               num2 = password
           num1 = num2 & m_16
           num1 = num1 >> 4
           num2 = num2 << 28
           num1 = num1 + num2
           flag = False
       elif c == '3':
           length = not flag
           if not length :
               num2 = password
           num1 = num2 & m_8
           num1 = num1 >> 3
           num2 = num2 << 29
           num1 = num1 + num2
           flag = False
       elif c == '4':
           length = not flag
           if not length:
               num2 = password
           num1 = num2 << 1
           num2 = num2 >> 31
           num1 = num1 + num2
           flag = False
       elif c == '5':
           length = not flag
           if not length:
               num2 = password
           num1 = num2 << 5
           num2 = num2 >> 27
           num1 = num1 + num2
           flag = False
       elif c == '6':
           length = not flag
           if not length:
               num2 = password
           num1 = num2 << 12
           num2 = num2 >> 20
           num1 = num1 + num2
           flag = False
       elif c == '7':
           length = not flag
           if not length:
               num2 = password
           num1 = num2 & 0xFF00L
           num1 = num1 + (( num2 & 0xFFL ) << 24 )
           num1 = num1 + (( num2 & 0xFF0000L ) >> 16 )
           num2 = ( num2 & m_16777216 ) >> 8
           num1 = num1 + num2
           flag = False
       elif c == '8':
           length = not flag
           if not length:
               num2 = password
           num1 = num2 & 0xFFFFL
           num1 = num1 << 16
           num1 = num1 + ( num2 >> 24 )
           num2 = num2 & 0xFF0000L
           num2 = num2 >> 8
           num1 = num1 + num2
           flag = False
       elif c == '9':
           length = not flag
           if not length:
               num2 = password
           num1 = ~num2
           flag = False
       else :
           num1 = num2
       num2 = num1
   return num1 & m_1

def ownTestCalcPass (passwd, nonce, expected) :

       res = ownCalcPass(passwd, nonce)
       m = passwd+' '+nonce+' '+str(res)+' '+str(expected)
       if res == long(expected) :
               print 'PASS '+m
       else : 
               print 'FAIL '+m

if __name__ == '__main__':

   import sys
   ownTestCalcPass('12345','603356072','25280520')
   ownTestCalcPass('12345','410501656','119537670')

</lang>