How to implement the Luhn alorithm in OCL - ocl

I am trying to find the Luhn algorithm in OCL to check the validity of ISIN. Can anyone provide a code example would it be great!

In the German Wikipedia article about the Luhns algorithm (https://de.wikipedia.org/wiki/Luhn-Algorithmus) you can find an example to calculate the value for an ident of 446-667-651. The algorithm below calculates the correct value of 40.
let list = '446667651'.ToCharArray.strToInt in
Sequence{1..list->size}
->Collect(i|
if (list->size-i).Mod(2)=0 then
list.at(i)
else
(list.at(i)*2).Mod(9)
endif)
->Sum
Maybe you need some adaptions for calculating the value for ISINs.

In pure OCL using the example from https://en.wikipedia.org/wiki/Luhn_algorithm
let s = Sequence{7,9,9,2,7,3,9,8,7,1} in
(Sequence{1..s->size()}
->collect(i |
let t = s->at(i) in
if i.mod(2) = 1
then t
else let tt = 2 * t in tt.div(10) + tt.mod(10)
endif)
->sum()*9)
.mod(10)

Create a class:
Attribute NextMult1Or2:Integer
Method MultWith2Or1SumBiggerThan10(v:Integer):Integer
Method GetCheckSum(input:String):Integer
The first method MultWith2Or1SumBiggerThan10:
let res=v*self.NextMult1Or2 in
(
if self.NextMult1Or2=2 then
self.NextMult1Or2:=1
else
self.NextMult1Or2:=2
endif;
if res>10 then
res-9
else
res
endif
)
And the second method GetCheckSum(input:String):Integer
self.NextMult1Or2:=2;
input.ToCharArray->collect(c|
let i=Integer.Parse(c) in (
self.MultWith2Or1SumBiggerThan10(i)
)
)->sum
To calculate the checksum - send in all but check digit to GetCheckSum - the check digit is (((res+10) / 10).Truncate*10)-res (ie the diff from nearest 10:th above)
To check a sequence send in all including check digit to GetCheckSum - if res.Mod(10)= 0 it has passed

Related

Convert List into a integer or float

so i'm having a problem converting to a list to integer or float. what i mean in converting is like this. i have a list that has one element.
newList = ['2.0G']
i want that to convert into this
numFloat = 2.0
or
numInt = 2
i tried regex to extract the number from string so i can assign it to another variable
firstVariable = re.findall(r"[-+]?\d*\.\d+|\d+", newList[0])
i have to keep calling the index in firstVariable to access the 2.0 or 2
Does this work ?
newList = ['2.0G']
numFloat = ''.join([i for i in newList[0] if i.isdigit() or i == '.'])
print(numFloat)
The above code will print 2.0 to the console.
What I am doing here, is that I am going through each and every item in the first item of the list , and then checking if its a digit or a .. If its not any one of these I move to the next character.
Please note that I am doing newList[0] because you mentioned that your list has only one element.
Please let me know if this works for you.
Thanks.

Retrieve values from an array - get "cannot call value of non-function type String"

I'm trying to retrieve a value from an array, based on an index parsed from a string of digits. I'm stuck on this error, and the other answers to similar questions in this forum appear to be for more advanced developers (this is my first iOS app).
The app will eventually look up weather reports ("MAFOR" groupings of 5 digits each) from a web site, parse each group and lookup values from arrays for wind direction, speed, forecast period etc using each character.
The playground code is below, appreciate any help on where I am going wrong (look for ***)
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
// create array for Forecast Period
let forecastPeriodArray = ["Existing conditions at beginning","3 hours","6 hours","9 hours","12 hours","18 hours","24 hours","48 hours","72 hours","Occasionally"]
// create array for Wind Direction
let windDirectionArray = ["Calm","Northeast","East","Southeast","South","Southwest","West","Northwest","North","Variable"]
// create array for Wind Velocity
let windVelocityArray = ["0-10 knots","11-16 knots","17-21 knots","22-27 knots","28-33 knots","34-40 knots","41-47 knots","48-55 knots","56-63 knots","64-71 knots"]
// create array for Forecast Weather
let forecastWeatherArray = ["Moderate or good visibility (> 3 nm.","Risk of ice accumulation (temp 0C to -5C","Strong risk of ice accumulkation (air temp < -5C)","Mist (visibility 1/2 to 3 nm.)","Fog (visibility less than 1/2 nm.)","Drizzle","Rain","Snow, or rain and snow","Squally weather with or without showers","Thunderstorms"]
// retrieve full MAFOR line of several information groups (this will be pulled from a web site)
var myMaforLineString = "11747 19741 13757 19751 11730 19731 11730 13900 11630 13637"
// split into array components wherever " " is encountered
var myMaforArray = myMaforLineString.components(separatedBy: " ")
let count = myMaforArray.count
print("There are \(count) items in the array")
// Go through each group and parse out the needed digits
for maforGroup in myMaforArray {
print("MAFOR group \(maforGroup)")
// get Forecast Period
var idx = maforGroup.index(maforGroup.startIndex, offsetBy: 1)
var periodInt = maforGroup[idx]
print("periodInt is \(periodInt)")
// *** here is where I am stuck... trying to use the periodInt index value to retrieve the description from the ForecastPeriodArray
var periodDescription = forecastPeriodArray(periodInt)
print("Forecast period = (forecastPeriodArray(periodInt)")
// get Wind Direction
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 2)
var directionInt = maforGroup[idx]
print("directionInt is \(directionInt)")
// get Wind Velocity
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 3)
var velocityInt = maforGroup[idx]
print("velocityInt is \(velocityInt)")
// get Weather Forecast
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 4)
var weatherInt = maforGroup[idx]
print("weatherInt is \(weatherInt)")
}
#shallowThought was close.
You are trying to access an array by its index, therefore use the array[index] notation. But your index has to be of the correct type. forecastPeriodArray[periodInt] therefore does not work since periodInt is not an Int as the name would suggest. Currently it is of type Character which does not make much sense.
What you are probably trying to achieve is convert the character to an integer and use that to access the array:
var periodInt = Int(String(maforGroup[idx]))!
You might want to add error handling for the case when the character does not actually represent an integer.

Format long number to shorter version in Lua

I'm trying to figure out how I would go about formatting a large number to the shorter version by appending 'k' or 'm' using Lua. Example:
17478 => 17.5k
2832 => 2.8k
1548034 => 1.55m
I would like to have the rounding in there as well as per the example. I'm not very good at Regex, so I'm not sure where I would begin. Any help would be appreciated. Thanks.
Pattern matching doesn't seem like the right direction for this problem.
Assuming 2 digits after decimal point are kept in the shorter version, try:
function foo(n)
if n >= 10^6 then
return string.format("%.2fm", n / 10^6)
elseif n >= 10^3 then
return string.format("%.2fk", n / 10^3)
else
return tostring(n)
end
end
Test:
print(foo(17478))
print(foo(2832))
print(foo(1548034))
Output:
17.48k
2.83k
1.55m
Here a longer form, which uses the hint from Tom Blodget.
Maybe its not the perfect form, but its a little more specific.
For Lua 5.0, replace #steps with table.getn(steps).
function shortnumberstring(number)
local steps = {
{1,""},
{1e3,"k"},
{1e6,"m"},
{1e9,"g"},
{1e12,"t"},
}
for _,b in ipairs(steps) do
if b[1] <= number+1 then
steps.use = _
end
end
local result = string.format("%.1f", number / steps[steps.use][1])
if tonumber(result) >= 1e3 and steps.use < #steps then
steps.use = steps.use + 1
result = string.format("%.1f", tonumber(result) / 1e3)
end
--result = string.sub(result,0,string.sub(result,-1) == "0" and -3 or -1) -- Remove .0 (just if it is zero!)
return result .. steps[steps.use][2]
end
print(shortnumberstring(100))
print(shortnumberstring(200))
print(shortnumberstring(999))
print(shortnumberstring(1234567))
print(shortnumberstring(999999))
print(shortnumberstring(9999999))
print(shortnumberstring(1345123))
Result:
> dofile"test.lua"
100.0
200.0
1.0k
1.2m
1.0m
10.0m
1.3m
>
And if you want to get rid of the "XX.0", uncomment the line before the return.
Then our result is:
> dofile"test.lua"
100
200
1k
1.2m
1m
10m
1.3m
>

Log base 2 calculation in python

I am trying to calculate the average disorder in ID trees. My code is below:
Republican_yes = yes.count('Republican')
Democrat_yes = yes.count('Democrat')
Republican_no = no.count('Republican')
Democrat_no = no.count('Democrat')
Indep_yes = yes.count('Independent')
Indep_no = no.count('Independent')
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
return avgdisorder
why do I keep getting math domain error?
Check if the lengths are 0 or not, else you will get MathError.
if len(yes):
disorder_yes= Republican_yes/len(yes)*(math.log(float(Republican_yes)/len(yes),2))+ Democrat_yes/len(yes)*(math.log(float(Democrat_yes)/len(yes),2))+Indep_yes/len(yes)*(math.log(float(Indep_yes)/len(yes),2))
if len(no):
disorder_no= Republican_no/len(no)*(math.log(float(Republican_no)/len(no),2))+Democrat_no/len(no)*(math.log(float(Democrat_no)/len(no),2))+Indep_no/len(no)*(math.log(float(Indep_no)/len(no),2))
if len(yes) or len(no):
avgdisorder = -len(yes)/(len(yes)+len(no))*disorder_yes - len(no)/(len(yes)+len(no))*disorder_no
If you want, you can always add the else clause for all 3 if statements as per your requirement.

Rainbow attack through python lookup is failing.

I have some issues with an assignment have been given. The gist is that I have to do a rainbow attack on a "car fop".
With a generator table, the RainbowAttack.py script the following:
The key broadcasts to car (in this case the adversary)
The car/eve responds with a challenge u.
The key then responds with a hash consisting of MD5(s||u).
Eve now uses the Rainbow-table to crack s.
We use MD5 to hash our response and our keys
And then we use our reduction function on the hash and take the first 28 bit
f_i(x) = (f(x)+i) mod 2^28.
My hash and redcution function
def f(s, i=0):
"""Lowest 28 bits of (MD5(s||u) % i)"""
digest = '0x' + md5.new(str(s) + str(u)).hexdigest()
result = hex((int(digest, 16) + i) % 2**BIT_SIZE)[:BIT_SIZE/4+2]
return result
anyways when we run our script we receive the response we calculate all successors and compare them to the end points in the rainbow-table if a match is found we get the start point of the collision and now we check if the key is in the chain from start point to end point if one of the keys here is the same as the response we got from the fop we know that the previous key is the secret to opening the car door.
At the moment we are only able to actually find the key when it is in the start position or end position of the rainbow-table and not if it's in the chain.
Here is the code for the loops that check the succsessors and that check if any of our successors are in the rainbowtable and if they are we check if our response from the car fop is in there if it is we have our key.
It might be a problem that is caused when we calculate our successors since the reduction function will be diffrent than the one used on the key (i will increment making the reduction function slightly diffrent for all keys in a chain)
def find_key(table, r):
"""Search for matching respons in Rainbow-table"""
succ = [r]
print r
for i in xrange(1, CHAIN_LEN):
succ.append(f(succ[i-1],i))
for key, value in table.iteritems():
if value in succ:
print "\tCollition: %s -> %s" % (key, value)
ss = key
for i in xrange(0, CHAIN_LEN):
rs = f(ss, i)
if rs==r:
return ss
ss = rs
return -1
the rainbowtable and the files can be found here (github)
(derp.py(rainbow attack) and table1.csv(change name to table.csv))