Dado n
(o número de jogadores), t
(o valor limite) e s
(o segredo), são apresentados os n
segredos gerados pelo algoritmo de Compartilhamento Secreto de Shamir .
O Algoritmo
Para os propósitos deste desafio, os cálculos serão feitos em GF (251) (o campo finito de tamanho 251
, também conhecido como número inteiro mod 251 ). Normalmente, o campo seria escolhido de tal forma que seu tamanho seja um primo muito maior que n
. Para simplificar o desafio, o tamanho do campo será constante. 251
foi escolhido porque é o maior número primo representável por um número inteiro não assinado de 8 bits.
- Gere
t-1
números inteiros aleatórios no intervalo (inclusive)[0, 250]
. Rotular essas um 1 por meio de um t-1 . - Construa um
t-1
polinômio de th grau usandos
como valor constante e os números inteiros aleatórios da etapa 1 como os coeficientes das potências dex
: f (x) = s + x * a 1 + x 2 * a 2 + ... + x t- 1 * a t-1 . - Saída
(f(z) mod 251)
para cada umz
na faixa (inclusive)[1, n]
.
Implementação de referência
#!/usr/bin/env python
from __future__ import print_function
import random
import sys
# Shamir's Secret Sharing algorithm
# Input is taken on the command line, in the format "python shamir.py n t s"
n, t, s = [int(x) for x in sys.argv[1:4]]
if t > n:
print("Error: t must be less than or equal to n")
exit()
if n not in range(2, 251):
print("Error: n must be a positive integer less than 251")
exit()
if t not in range(2, 251):
print("Error: t must be a positive integer less than 251")
exit()
if s not in range(251):
print("Error: s must be a non-negative integer less than 251")
exit()
p = 251
a = [random.randrange(0, 251) for x in range(t-1)]
def f(x):
return s + sum(c*x**(i+1) for i,c in enumerate(a))
# Outputting the polynomial is for explanatory purposes only, and should not be included
# in the output for the challenge
print("f(x) = {0} + {1}".format(s, ' + '.join('{0}*x^{1}'.format(c, i+1) for i,c in enumerate(a))))
for z in range(1, n+1):
print(f(z) % p)
Verificação
O seguinte snippet de pilha pode ser usado para verificar as saídas:
Regras
s
será um número inteiro não negativo menor que251
en
et
números inteiros positivos menores que251
e maiores que1
. Além disso, você tem a garantia de que as entradas são válidas (significadot <= n
).- A entrada e a saída podem estar em qualquer formato razoável, inequívoco e consistente.
- Números aleatórios devem ser amostrados a partir de uma distribuição uniforme - cada valor possível deve ter igual probabilidade de ser escolhido.
code-golf
number-theory
random
cryptography
polynomials
code-golf
number
code-golf
math
number
sequence
code-golf
quine
code-generation
code-golf
arithmetic
set-theory
code-golf
sequence
code-golf
code-golf
string
math
fastest-code
optimization
code-golf
code-golf
internet
stack-exchange-api
code-golf
array-manipulation
code-golf
string
internet
string
code-challenge
internet
test-battery
code-golf
math
pi
code-golf
arithmetic
primes
code-golf
array-manipulation
code-golf
string
code-golf
string
palindrome
code-golf
sequence
number-theory
fastest-algorithm
code-golf
math
number
base-conversion
code-golf
number-theory
sorting
subsequence
search
code-golf
permutations
code-challenge
popularity-contest
code-generation
Mego
fonte
fonte
z
ef(z)
? Se eu imprimir uma matriz def(z)
s em ordem,z
está implícito no índice.[[1, 5], [2, 2], [3, 9], [4, 14]]
não contém mais informações que[5, 2, 9, 14]
.Respostas:
Gelatina , 15 bytes
Espera t , n , e s como argumentos de linha de comando. Experimente online!
Como funciona
fonte
Mathematica,
5956 bytesLeva três argumentos na ordem t , n , e s . Constrói um array 2D com n linhas et -1 colunas. Cada vetor de linha j , numerado de 1 a n , contém os poderes de j a j t -1 . Então, um vetor de coeficientes inteiros aleatórios no intervalo de 0 a 250 é criado com os valores t -1. Isso é multiplicado por matriz com a matriz 2d e, em seguida, s é adicionado elemento a elemento e é obtido o módulo 251 para obter o valor do polinômio em cada um dos n pontos.
fonte
Sum
!Mod[x#+#2&~Fold~RandomInteger[250,#2-1]x+#3/.x->Range@#,251]&
CJam,
2725 bytesTeste aqui.
fonte
Pitão, 24 bytes
Experimente online!
Ordem de entrada:
n
s
t
separados por avanço de linha.fonte
JavaScript, 181 bytes
Ungolfed:
Eu não sei como checá-lo corretamente, mas sei que foi um problema fazer JS mapear em uma nova matriz, pois aparentemente
.map
ignora valores indefinidos. Se alguém vê alguma maneira de melhorar, ou falhas, não hesite em me avisar.fonte
(n,t,s,A=f=>Array(t-1).fill(0).map(f),r=A($=>Math.random()*251))=> A((l,i,_,p=0)=>(r.map((k,c)=>p+=k*Math.pow(i,c)),s+p))
n
, o que parece errado. Seu código também parece estar assumindo uma indexação baseada em 1.[...Array()]
é um pouco menor quefiil()
. Além disso, as duas últimas linhas podem ser reduzidas parareturn _.map(f);
C #,
138134 bytesC # lambda onde estão as entradas
int
e a saída é umIEnumerable<double>
. Você pode tentar meu código no .NetFiddle .Não tenho 100% de certeza sobre a validade do meu algoritmo. Por favor, comente se entendi algo errado.
4 bytes salvos com o truque de @ raggy .
fonte
MATL ,
2019 bytesOrdem de entrada é
t
,s
,n
.Experimente online!
Explicação
fonte
Julia, 48 bytes
Experimente online!
fonte
JavaScript (ES6), 116 bytes
Eu gostaria de pensar que este é um dos raros casos em que
reduce
batemap
.fonte
Python 3 com NumPy , 103 bytes
Posso dizer honestamente que nunca esperei usar o NumPy para código de golfe ...
Uma função anônima que recebe entrada por meio de argumento e retorna uma lista.
Como funciona
Experimente no Ideone
fonte
J ,
3230 bytesFaz uma lista com os valores n , t e s .
Economizou 2 bytes usando a idéia de substituição no índice 0 da solução de @ Dennis .
Explicação
fonte
Java 8, 224 bytes:
Uma expressão lambda do Java 8. Produz uma matriz inteira separada por vírgula e funciona perfeitamente até que os valores na matriz de saída cheguem além do intervalo do
long
tipo de dados inteiro assinado em Java ou de 64 bits, no qual-200
é gerado na matriz.Experimente Online! (Ideona)
fonte