How to find the base value in modular arithmetic? - encryption

I need an efficient formula of some kind that will allow one to figure out the original message(msg) with regards to the following formula: C = msg^e mod N. If a user is provided with C, e and N, is there an efficient way to calculate msg? In this example, C is the ciphertext, e is the public key and N is a public modulus.
I have done some research on what modular arithmetic is all about and looked over some detailed explanations, however, no articles have shown me how to figure out a problem such as this.

Modulus is a non-reversible operation. At best, you know that msg ^ e = C + k*N, and need to determine the value of k.
Consider the following simple case:
e = 2
N = 10
msg = 1 | C = 1 'Note1
msg = 2 | C = 4 'Note2
msg = 3 | C = 9 'Note3
msg = 4 | C = 6 'Note4
msg = 5 | C = 5
msg = 6 | C = 6 'Note4
msg = 7 | C = 9 'Note3
msg = 8 | C = 4 'Note2
msg = 9 | C = 1 'Note1
msg = 10 | C = 0
It should immediately be obvious that if C = 6, this could mean that Msg = 6 or that Msg = 4 (Or Msg = 24, et cetera, ad infinitum) with no way to tell the difference without more information.
However, given the same msg for different known values of e and N, then you can narrow down the possibilities like so:
e = 3
N = 10
Msg = 1 | C = 1
Msg = 2 | C = 8
Msg = 3 | C = 7
Msg = 4 | C = 4 'We can now see that this
Msg = 5 | C = 5
Msg = 6 | C = 6 'Is different from this
Msg = 7 | C = 3
Msg = 8 | C = 2
Msg = 9 | C = 9
Msg = 10 | C = 0

Related

Finding solutions to the equation a + b + gcd(a, b) = n

I have a question that, we are given n; We should find different two numbers: a and b, such that, a + b + gcd(a, b) = n. How can we find it?
a + b + gcd(a, b) =
gcd(a, b) * da + gcd(a, b) * db + gcd(a, b) =
gcd(a, b)* (da + db + 1)
So you have to get arbitrary factorization of n into two divisors, assign one divisor >= 3 to the sum d = (da + db + 1), and another divisor to gcd(a, b).
Subdivide d-1 value into two mutual prime parts da and db
Example (just some possible solutions for "universal answer value"):
n = 42 = 6 x 7
da + db + 1 = 6
da = 2 //arbitrary subdivision, da is mutual prime with db, OK
db = 3
gcd = 7
a = 14
b = 21
n = 14 + 21 + 7 = 42
da = 1 //arbitrary subdivision
db = 4
a = 7
b = 28
n = 7 + 28 + 7 = 42
da + db + 1 = 7
da = 2 // Error - gcd(da,db)>1, they are not mutual prime, subdivision is not suitable
db = 4
da = 1 //it's OK
db = 5
gcd = 6
6 + 30 + 6 = 42
n = 14 * 3
da = 5, db = 8
15 + 24 + 3 = 42

Floyd Warshall algorithm with adjacency matrix

I'm trying to implement the floyd warshall algorithm but it won't work correctly.
What I want is the shortest path distances from one vertex to another written in a matrix d and the predecessors in a matrix pred. The input is an adjacency matrix which contains all of the edge weights.
function FloWa(C)
N = size(C)
n = min(C[1],C[2])
pred = -1*ones(C[1],C[2])
d = C
for k in 1:n
for i in 1:n
for j in 1:n
if d[i,j] > d[i,k] + d[k,j]
if pred[i,k] == -1
pred[i,j] = k
else
pred[i,j] = pred[k,j]
end
d[i,j] = d[i,k] + d[k,j]
end
if i == j && d[i,i] < 0
println("negative Dicycle")
end
end
end
end
return d, pred
end
When i am running my code with the matrix
A = [0 2 1 4 5 1; 1 0 4 2 3 4; 2 1 0 1 2 4; 3 5 2 0 3 3; 2 4 3 4 0 1; 3 4 7 3 1 0]
i don't get the right results.
For d i get the same matrix as A and pred is printed as an Array{Float64}(0,1).
I have not checked the implementation of the algorithm, but you seem to initialize pred and d incorrectly. Here is a way to do it that is I assume you indented:
n = size(C, 1) # get number of rows in C
#assert n == size(C, 2) # make sure that C is square or throw an error
pred = fill(-1, size(C)) # fill pred with -1 and make it have the same size as C
d = copy(C) # d is a copy of C

conditional sampling without replacement

I am attempting to write a simulation that involves randomly re-assigning items to categories with some restrictions.
Lets say I have a collection of pebbles 1 to N distributed across buckets A through J:
set.seed(100)
df1 <- data.frame(pebble = 1:100,
bucket = sample(LETTERS[1:10], 100, T),
stringsAsFactors = F)
head(df1)
#> pebble bucket
#> 1 1 D
#> 2 2 C
#> 3 3 F
#> 4 4 A
#> 5 5 E
#> 6 6 E
I want to randomly re-assign pebbles to buckets. Without restrictions I could do it like so:
random.permutation.df1 <- data.frame(pebble = df1$pebble, bucket = sample(df1$bucket))
colSums(table(random.permutation.df1))
#> A B C D E F G H I J
#> 4 7 13 14 12 11 11 10 9 9
colSums(table(df1))
#> A B C D E F G H I J
#> 4 7 13 14 12 11 11 10 9 9
Importantly this re-assigns pebbles while ensuring that each bucket retains the same number (because we are sampling without replacement).
However, I have a set of restrictions such that certain pebbles cannot be assigned to certain buckets. I encode the restrictions in df2:
df2 <- data.frame(pebble = sample(1:100, 10),
bucket = sample(LETTERS[1:10], 10, T),
stringsAsFactors = F)
df2
#> pebble bucket
#> 1 33 I
#> 2 39 I
#> 3 5 A
#> 4 36 C
#> 5 55 J
#> 6 66 A
#> 7 92 J
#> 8 95 H
#> 9 2 C
#> 10 49 I
The logic here is that pebbles 33 and 39 cannot be placed in bucket I, or pebble 5 in bucket A, etc. I would like to permute which pebbles are in which bucket subject to these restrictions.
So far, I've thought of tackling it in a loop as below, but this does not result in buckets retaining the same number of pebbles:
perms <- character(0)
cnt <- 1
for (p in df1$pebble) {
perms[cnt] <- sample(df1$bucket[!df1$bucket %in% df2$bucket[df2$pebble==p]], 1)
cnt <- cnt + 1
}
table(perms)
#> perms
#> A B C D E F G H I J
#> 6 7 12 22 15 1 14 7 7 9
I then tried sampling positions, and then removing that position from the available buckets and the available remaining positions. This is also not working, and I suspect it is because I am sampling my way into branches of the tree that do not yield solutions.
set.seed(42)
perms <- character(0)
cnt <- 1
ids <- 1:nrow(df1)
bckts <- df1$bucket
for (p in df1$pebble) {
id <- sample(ids[!bckts %in% df2$bucket[df2$pebble==p]], 1)
perms[cnt] <- bckts[id]
bckts <- bckts[-id]
ids <- ids[ids!=id]
cnt <- cnt + 1
}
table(perms)
#> perms
#> A B C D E F G J
#> 1 1 4 1 2 1 2 2
Any thoughts or advice much appreciated (and apologies for the length).
EDIT:
I foolishly forgot to clarify that I was previously solving this by just resampling until I got a draw that didn't violate any of the conditions in df2, but I now have many conditions such that this would make my code take too long to run. I am still up for trying to force it if I could figure out a way to make forcing it faster.
I have a solution (I managed to write it in base R, but the data.table solution is easier to understand and write:
random.permutation.df2 <- data.frame(pebble = df1$pebble, bucket = rep(NA,length(df1$pebble)))
for(bucket in unique(df1$bucket)){
N <- length( random.permutation.df2$bucket[is.na(random.permutation.df2$bucket) &
!random.permutation.df2$pebble %in% df2$pebble[df2$bucket == bucket] ] )
random.permutation.df2$bucket[is.na(random.permutation.df2$bucket) &
!random.permutation.df2$pebble %in% df2$pebble[df2$bucket == bucket] ] <-
sample(c(rep(bucket,sum(df1$bucket == bucket)),rep(NA,N-sum(df1$bucket == bucket))))
}
The idea is to sample the authorised peeble for each bucket: those that are not in df2, and those that are not already filled. You sample then a vector of the good length, choosing between NAs (for the following buckets values) and the value in the loop, and voilà.
Now easier to read with data.table
library(data.table)
random.permutation.df2 <- setDT(random.permutation.df2)
df2 <- setDT(df2)
for( bucketi in unique(df1$bucket)){
random.permutation.df2[is.na(bucket) & !pebble %in% df2[bucket == bucketi, pebble],
bucket := sample(c(rep(bucketi,sum(df1$bucket == bucket)),rep(NA,.N-sum(df1$bucket == bucket))))]
}
it has the two conditions
> colSums(table(df1))
A B C D E F G H I J
4 7 13 14 12 11 11 10 9 9
> colSums(table(random.permutation.df2))
A B C D E F G H I J
4 7 13 14 12 11 11 10 9 9
To verify that there isn't any contradiction with df2
> df2
pebble bucket
1: 37 D
2: 95 H
3: 90 C
4: 80 C
5: 31 D
6: 84 G
7: 76 I
8: 57 H
9: 7 E
10: 39 A
> random.permutation.df2[pebble %in% df2$pebble,.(pebble,bucket)]
pebble bucket
1: 7 D
2: 31 H
3: 37 J
4: 39 F
5: 57 B
6: 76 E
7: 80 F
8: 84 B
9: 90 H
10: 95 D
Here a brute force approach where one simply tries long enough until a valid solution is found:
set.seed(123)
df1 <- data.frame(pebble = 1:100,
bucket = sample(LETTERS[1:10], 100, T),
stringsAsFactors = F)
df2 <- data.frame(pebble = sample(1:100, 10),
bucket = sample(LETTERS[1:10], 10, T),
stringsAsFactors = F)
random.permutation.df1 <- data.frame(pebble = df1$pebble, bucket = sample(df1$bucket))
Random permutation does not match the condition, so try new ones:
merge(random.permutation.df1, df2)
#> pebble bucket
#> 1 60 J
while(TRUE) {
random.permutation.df1 <- data.frame(pebble = df1$pebble, bucket = sample(df1$bucket))
if(nrow(merge(random.permutation.df1, df2)) == 0)
break;
}
New permutation matches the condition:
merge(random.permutation.df1, df2)
#> [1] pebble bucket
#> <0 Zeilen> (oder row.names mit Länge 0)
colSums(table(random.permutation.df1))
#> A B C D E F G H I J
#> 7 12 11 9 14 7 11 11 11 7
colSums(table(df1))
#> A B C D E F G H I J
#> 7 12 11 9 14 7 11 11 11 7

Aggregated rolling average with a conditional statement in R

I have a data frame that follows the following format.
match team1 team2 winningTeam
1 A D A
2 B E E
3 C F C
4 D C C
5 E B B
6 F A A
7 A D D
8 D A A
What I want to do is to crate variables that calculates the form of both team 1 and 2 over the last x matches. For example, I would want to create a variable called team1_form_last3_matches which for match 8 would be 0.33 (as they won 1 of their last 3 matches) and there would also be a variable called team2_form_last3_matches which would be 0.66 in match 8 (as they won 2 of their last 3 matches). Ideally I would like to be able to specify the number of previous matches to be considered when calculating the teamx_form_lasty variable and those variables to be automatically created. I have tried a bunch of approaches using dplyr, zoo rolling mean functions and a load of nested for / if statements. However, I have not quite cracked it and certainly not in an elegant way. I feel like I am missing a simple solution to this generic problem. Any help would be much appreciated!
Cheers,
Jack
This works for t1l3, you will need to replicate it for t2.
dat <- data.frame(match = c(1:8), team1 = c("A","B","C","D","E","F","A","D"), team2 = c("D","E","F","C","B","A","D","A"), winningTeam = c("A","E","C","C","B","A","D","A"),stringsAsFactors = FALSE)
dat$t1l3 <- c(NA,sapply(2:nrow(dat),function(i) {
df <- dat[1:(i-1),] #just previous games, i.e. excludes current game
df <- df[df$team1==dat$team1[i] | df$team2==dat$team1[i],] #just those containing T1
df <- tail(df,3) #just the last three (or fewer if there aren't three previous games)
return(sum(df$winningTeam==dat$team1[i])/nrow(df)) #total wins/total games (up to three)
}))
How about something like:
dat <- data.frame(match = c(1:8), team1 = c("A","B","C","D","E","F","A","D"), team2 = c("D","E","F","C","B","A","D","A"), winningTeam = c("A","E","C","C","B","A","D","A"))
match team1 team2 winningTeam
1 1 A D A
2 2 B E E
3 3 C F C
4 4 D C C
5 5 E B B
6 6 F A A
7 7 A D D
8 8 D A A
Allteams <- c("A","B","C","D","E","F")
# A vectorized function for you to use to do as you ask:
teamX_form_lastY <- function(teams, games, dat){
sapply(teams, function(x) {
games_info <- rowSums(dat[,c("team1","team2")] == x) + (dat[,"winningTeam"] == x)
lookup <- ifelse(rev(games_info[games_info != 0])==2,1,0)
games_won <- sum(lookup[1:games])
if(length(lookup) < games) warning(paste("maximum games for team",x,"should be",length(lookup)))
games_won/games
})
}
teamX_form_lastY("A", 4, dat)
A
0.75
# Has a warning for the number of games you should be using
teamX_form_lastY("A", 5, dat)
A
NA
Warning message:
In FUN(X[[i]], ...) : maximum games for team A should be 4
# vectorized input
teamX_form_lastY(teams = c("A","B"), games = 2, dat = dat)
A B
0.5 0.5
# so you ca do all teams
teamX_form_lastY(teams = Allteams, 2, dat)
A B C D E F
0.5 0.5 1.0 0.5 0.5 0.0

what is the mode 'collapse' in as.undirected function

The graph is
a b 1
a b 2
b a 3
a a 4
a a 2
g = read.graph('this_file.ncol', format = 'ncol', directed = TRUE)
when I use the as.undirected(g,mode="collapse"), I get
a a 7
a b 5
Why? What I expect is
a a 6
a b 6
Is this a bug, or I do not understand the meaning of 'collapse'?
I can reproduce this. This is what I get:
cat(file = tmp <- tempfile(),
"a b 1
a b 2
b a 3
a a 4
a a 2
")
g <- read.graph(tmp, format = 'ncol', directed = TRUE)
g2 <- as.undirected(g, mode = "collapse")
get.data.frame(g2)
# from to weight
# 1 a a 7
# 2 a b 5
igraph.version()
# [1] "0.7.1"
So it seems that it is indeed a bug. Please report it at https://github.com/igraph/igraph. Thanks.
It seems that as.undirected() has problems with multiple edges. This is a workaround:
# g3 <- as.undirected(simplify(g, remove.loops = FALSE))
# get.data.frame(g3)
# from to weight
# 1 a a 6
# 2 a b 6

Resources