python編寫函數(shù)素數(shù),Python定義函數(shù)輸出素數(shù)個數(shù)

Python編寫函數(shù)prime,判斷一個數(shù)是否為素數(shù)。調用該函數(shù)判斷從鍵盤中輸入的數(shù)?

# 判斷數(shù)N是否素數(shù)

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設,洛南企業(yè)網(wǎng)站建設,洛南品牌網(wǎng)站建設,網(wǎng)站定制,洛南網(wǎng)站建設報價,網(wǎng)絡營銷,網(wǎng)絡優(yōu)化,洛南網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

def Is_Prime(N):

for i in range(2,int(N**(1/2))+1):

if N % i == 0:

return False

else:

return True

程序縮進如圖所示

Python編寫程序,求出最小的100個素數(shù)

#!/usr/bin/python3

# -*- coding:utf-8 -*-

# @FileName ?:Get_100_PrimeNumber.py

# @Time ? ? ?:2021/3/26 8:43

# @Author ? ?:Storm_duke

"""

獲取前100個素數(shù)

"""

import time

def is_prime(n):

"""判斷一個正整數(shù)是否為素數(shù)"""

if isinstance(n, (int, float)):

try:

if n == 1:

return False

for i in range(2, n):

if n % i == 0:

return False

return True

except Exception as ex:

return ex

else:

return False

if __name__ == "__main__":

start = time.perf_counter()

prime_list = []

t = 1

while t = 1:

if is_prime(t):

prime_list.append(t)

if prime_list.__len__() == 100:

break

t += 1

print("前100的素數(shù)是:{}".format(prime_list))

end = time.perf_counter()

print("耗時:{}".format(end - start))

如何用Python編寫一個素數(shù)環(huán)

此文主要目的,是向大家展示如何才能用python語言,來部署STARK算法。

STARKs(可擴容的透明知識論證)是創(chuàng)建一種證明的技術,這項證明中f(x)=y,其中f可能要花很長的時間來進行計算,但是這個證明可以被很快驗證。STARK是“雙重擴容”:對于一個需要t步驟的計算,這會花費大約O(t * log(t))步驟才能完成這個證明,這可能是最優(yōu)的情況,而且這需要通過~O(log2(t))個步驟才能驗證,對于中等大小的T值,它比原始計算快得多。STARKs也擁有隱私保護的“零知識證明”的特性,雖然我們將這類使用案例應用到其中,從而完成可驗證的延遲功能,不需要這類性質,所以我們不用擔心。

首先,先請幾項說明:

這個代碼還沒有完全審核;在實際使用案例中的情況,還不能保證

這部分代碼是還沒有達到理想狀態(tài)(是用Python語言寫的)

STARKs 的“真實情況” 傾向于使用二進制字段而不是素數(shù)域的特定應用程序效率的原因;但是,他們確實也表現(xiàn)出,這里寫出的代碼是合法并且可用的。

沒有一個真實的方法來使用STARK。它是一個非常寬泛的加密和數(shù)學架構,同時為不同的應用有不同的設置,以及連續(xù)的研究來減少證明者和驗證者的復雜性,同時提高可用性。

此文希望大家能夠知道,模運算和素數(shù)域是如何運行的,

并且和多項式概念,插值和估值進行結合。

現(xiàn)在,讓我們一起來了解吧!

MIMC

下面是STARK的功能展示:

def mimc(inp, steps, round_constants): start_time = time.time() for i in range(steps-1): inp = (inp**3 + round_constants[i % len(round_constants)]) % modulus print("MIMC computed in %.4f sec" % (time.time() - start_time)) return inp

我們選擇MIMC作為案例,因為它(i)很容易理解,(ii)在真實世界使用的很多。函數(shù)功能見下圖:

注意:在很多關于MIMC的討論中,你可以典型地看出使用了XOR,而不是+;這是因為MIMC可以在二進制情況下使用,其中添加是XOR;這里我們會在素數(shù)領域進行。

在我們的案例中,常數(shù)相對而言會是比較小的列表(例如,64位),這會一直連續(xù)地進行周期循環(huán)(也就說,在k[64]之后)。MIMC自身可以獲得這個特性,因為MIMC可以向后進行計算(從相應的輸出獲得輸入),但是往后計算需要比向前計算多花費100倍的時間(并且沒有方向可以同步進行)。所以你可以將往后計算的功能想象成計算不能同步的工作量證明,并且往前方向計算的功能可以作為驗證的過程。

x - x(2p-1)/3 是x - x3 的反函數(shù);根據(jù)費馬小定理,這是真實的,盡管這個定理沒有費馬大定理出名,但是依然對數(shù)學的貢獻很大。

我們嘗試使用STARK來進行更加有效的驗證,而不是讓驗證者必須在向前方向運行MIMC,在完成向后計算之后,證明者可以在向前方向進行STARK計算,并且驗證者可以很簡單地驗證STARK。我們希望計算STARK可以比MIMC向前和向后之間的運行速度差別要小,所以證明者的時間仍然是有初始的向后計算來主導的。而并不是STARK計算。STARK的認證會相對較快(在python語言算法中,可以是0.05-0.3秒),不論初始的計算時間有多長。

所有的計算會在2256 – 351 * 232 + 1個模內完成;我們使用素數(shù)模,因為它是小于2256 最大的素數(shù),其中乘法群包含了232 個子集(也就是說,有這樣一個數(shù)g,從而在完全232次循環(huán)之后,G素數(shù)環(huán)的連續(xù)冪模繞回到1),而且是按照6k+5的形式。首個特性是保證FFT和FRI算法的有效版本,其次是保證MIMC實際上可以向后計算(請見上面提到的x - x(2p-1)/3 使用方法)。

素域操作

我們通過建立方便的等級來進行素域的操作,同時也有多項式的操作。代碼如下,收首先是小數(shù)位數(shù):

class PrimeField(): def __init__(self, modulus): # Quick primality test assert pow(2, modulus, modulus) == 2 self.modulus = modulus def add(self, x, y): return (x+y) % self.modulus def sub(self, x, y): return (x-y) % self.modulus def mul(self, x, y): return (x*y) % self.modulus

并且使用擴展歐幾里得算法,來計算模塊逆轉(這和在素域中計算1/x相同):

# Modular inverse using the extended Euclidean algorithm def inv(self, a): if a == 0: return 0 lm, hm = 1, 0 low, high = a % self.modulus, self.modulus while low 1: r = high//low nm, new = hm-lm*r, high-low*r lm, low, hm, high = nm, new, lm, low return lm % self.modulus

上面的算法是相對昂貴的;幸運地是,對于特定的案例,我們需要做很多的模逆計算,有一個數(shù)學方法可以讓我們來計算很多逆運算,被稱為蒙哥馬利批量求逆:

使用蒙哥馬利批量求逆來計算模逆,其輸入為紫色,輸出為綠色,乘法門為黑色,紅色方塊是唯一的模逆。

下面的代碼是算法的體現(xiàn),其中包含一些特別的邏輯。如果我們正在求逆的集合中包含零,那么它會將這些零的逆設置為 0 并繼續(xù)前進。

def multi_inv(self, values): partials = [1] for i in range(len(values)): partials.append(self.mul(partials[-1], values[i] or 1)) inv = self.inv(partials[-1]) outputs = [0] * len(values) for i in range(len(values), 0, -1): outputs[i-1] = self.mul(partials[i-1], inv) if values[i-1] else 0 inv = self.mul(inv, values[i-1] or 1) return outputs

這部分算法接下來會驗證稱為非常重要的東西,特別是當我們開始和不同階的多項式進行計算的時候。

現(xiàn)在我們來看看一些多項式計算。我們把多項式當做一個數(shù)據(jù)集,其中的i是第i階(例如,x3 + 2x + 1變成[1, 2, 0, 1])。下面就是在一個點進行多項式估算的方法:

# Evaluate a polynomial at a point def eval_poly_at(self, p, x): y = 0 power_of_x = 1 for i, p_coeff in enumerate(p): y += power_of_x * p_coeff power_of_x = (power_of_x * x) % self.modulus return y % self.modulus

困難和挑戰(zhàn)

f.eval_poly_at([4, 5, 6], 2)的輸出是多少?模是31嗎?

下面的解釋就是答案

.其實也有代碼是多項式加法,減法,乘法和除法;這是很長的加減乘除運算。有一個很重要的內容是拉格朗日插值,它將一組 x 和 y 坐標作為輸入,并返回通過所有這些點的最小多項式(你可以將其視為多項式求值的逆):

# Build a polynomial that returns 0 at all specified xs def zpoly(self, xs): root = [1] for x in xs: root.insert(0, 0) for j in range(len(root)-1): root[j] -= root[j+1] * x return [x % self.modulus for x in root] def lagrange_interp(self, xs, ys): # Generate master numerator polynomial, eg. (x - x1) * (x - x2) * ... * (x - xn) root = self.zpoly(xs) # Generate per-value numerator polynomials, eg. for x=x2, # (x - x1) * (x - x3) * ... * (x - xn), by dividing the master # polynomial back by each x coordinate nums = [self.div_polys(root, [-x, 1]) for x in xs] # Generate denominators by evaluating numerator polys at each x denoms = [self.eval_poly_at(nums[i], xs[i]) for i in range(len(xs))] invdenoms = self.multi_inv(denoms) # Generate output polynomial, which is the sum of the per-value numerator # polynomials rescaled to have the right y values b = [0 for y in ys] for i in range(len(xs)): yslice = self.mul(ys[i], invdenoms[i]) for j in range(len(ys)): if nums[i][j] and ys[i]: b[j] += nums[i][j] * yslice return [x % self.modulus for x in b]

相關數(shù)學知識請參見此文的M-N部分。需要注意,我們也會有特別的方法lagrange_interp_4和lagrange_interp_2來加速次數(shù)小于 2 的拉格朗日插值和次數(shù)小于 4 的多項式運算。

快速傅立葉變換

如果你仔細閱讀上面的算法,你也許會發(fā)現(xiàn)拉格朗日插值和多點求值(即求在N個點處次數(shù)小于N的多項式的值)都需要耗費2次時間,例如對于1000個點求拉格朗日插值,需要幾百萬個步驟,而且100萬個點的拉格朗日插值需要萬億個步驟。這是不可接受的低效率,所以我們需要使用更加有效的算法,快速傅立葉變換。

FFT只需要花費O(n * log(n))的時間(也就是說,1000個點的計算需要10,000步,100萬個點的計算需要2000步),雖然它的范圍更受限制;x坐標必須是單位根部的完全集合,必須滿足N = 2k 階。也就是說,如果有N個點,那么x坐標必須某個P值的連續(xù)冪,1, p, p2, p3…,其中pN = 1。這個算法能夠用來進行多點計算和插值計算,而且只需要調整一個小參數(shù)。

下面就是算法詳情(這是個簡單的表達方式;更詳細內容可以參閱此處代碼)

def fft(vals, modulus, root_of_unity): if len(vals) == 1: return vals L = fft(vals[::2], modulus, pow(root_of_unity, 2, modulus)) R = fft(vals[1::2], modulus, pow(root_of_unity, 2, modulus)) o = [0 for i in vals] for i, (x, y) in enumerate(zip(L, R)): y_times_root = y*pow(root_of_unity, i, modulus) o[i] = (x+y_times_root) % modulus o[i+len(L)] = (x-y_times_root) % modulus return o def inv_fft(vals, modulus, root_of_unity): f = PrimeField(modulus) # Inverse FFT invlen = f.inv(len(vals)) return [(x*invlen) % modulus for x in fft(vals, modulus, f.inv(root_of_unity))]

你可以自己通過一些輸入來運行代碼,并且看看是否能得到想要的結果,當你使用eval_poly_at的時候,給出你期望得到的答案。例如:

fft.fft([3,1,4,1,5,9,2,6], 337, 85, inv=True) [46, 169, 29, 149, 126, 262, 140, 93] f = poly_utils.PrimeField(337) [f.eval_poly_at([46, 169, 29, 149, 126, 262, 140, 93], f.exp(85, i)) for i in range(8)] [3, 1, 4, 1, 5, 9, 2, 6]

傅里葉變換會把[x[0] …. x[n-1]]作為輸入,并且它的目標是輸出x[0] + x[1] + … + x[n-1]作為首個元素,x[0] + x[1] * 2 + … + x[n-1] * w**(n-1)作為第二個元素,等等;快速傅里葉變換可以通過把數(shù)據(jù)分為兩半,來完成這個,在兩邊都進行FFT,然后將結果結合在一起。

上圖就是信息如何進行FFT運算的解釋。請注意FFT是如何進行兩次數(shù)據(jù)復制,并且進行粘合,直到你得到一個元素。

現(xiàn)在,我們把所有部分組合起來,看看整件事情是如何:def mk_mimc_proof(inp, steps, round_constants),它生成運行 MIMC 函數(shù)的執(zhí)行結果的證明,其中給定的輸入為步驟數(shù)。首先,是一些 assert 函數(shù):

# Calculate the set of x coordinates xs = get_power_cycle(root_of_unity, modulus) column = [] for i in range(len(xs)//4): x_poly = f.lagrange_interp_4( [xs[i+len(xs)*j//4] for j in range(4)], [values[i+len(values)*j//4] for j in range(4)], ) column.append(f.eval_poly_at(x_poly, special_x))

擴展因子是我們將要拉伸的計算軌跡(執(zhí)行 MIMC 函數(shù)的“中間值”的集合)。

m2 = merkelize(column) # Pseudo-randomly select y indices to sample # (m2[1] is the Merkle root of the column) ys = get_pseudorandom_indices(m2[1], len(column), 40) # Compute the Merkle branches for the values in the polynomial and the column branches = [] for y in ys: branches.append([mk_branch(m2, y)] + [mk_branch(m, y + (len(xs) // 4) * j) for j in range(4)])

我們需要步數(shù)乘以擴展因子最多為 2^32,因為當 k 32 時,我們沒有 2^k 次的單位根。

computational_trace_polynomial = inv_fft(computational_trace, modulus, subroot) p_evaluations = fft(computational_trace_polynomial, modulus, root_of_unity)

我們首個計算會是得出計算軌跡;也就是說,所有的計算中間值,從輸入到輸出。

assert steps = 2**32 // extension_factor assert is_a_power_of_2(steps) and is_a_power_of_2(len(round_constants)) assert len(round_constants) steps

然后,我們會從將計算軌跡轉換為多項式,在單位根 g (其中,g^steps = 1)的連續(xù)冪的軌跡上“放下”連續(xù)值,然后我們對更大的集合——即單位根 g2 的連續(xù)冪,其中 g2^steps * 8 = 1(注意 g2^8 = g)的多項式求值。

# Generate the computational trace computational_trace = [inp] for i in range(steps-1): computational_trace.append((computational_trace[-1]**3 + round_constants[i % len(round_constants)]) % modulus) output = computational_trace[-1]

黑色: g1 的冪。紫色: g2 的冪。橙色:1。你可以將連續(xù)的單位根看作一個按這種方式排列的圓圈。我們沿著 g1的冪“放置”計算軌跡,然后擴展它來計算在中間值處(即 g2 的冪)的相同多項式的值。

我們可以將MIMC的循環(huán)常數(shù)轉換為多項式。因為這些循環(huán)常數(shù)鏈是非常通常發(fā)生地(在我們的測試中,每64個步驟都會進行),最終證明他們形成了64階的多項式,而且外面可以很容易計算出它的表達式,以及擴展式:

skips2 = steps // len(round_constants) constants_mini_polynomial = fft(round_constants, modulus, f.exp(subroot, skips2), inv=True) constants_polynomial = [0 if i % skips2 else constants_mini_polynomial[i//skips2] for i in range(steps)] constants_mini_extension = fft(constants_mini_polynomial, modulus, f.exp(root_of_unity, skips2))

假設其中有8192個步驟,并且有64個循環(huán)常數(shù)。這是我們想要做的:我們正在進行FFT,從而計算循環(huán)常數(shù)來作為g1128 的功能。然后我們在之間加入很多零,來完成g1本身的功能。因為g1128 大約每64步進行循環(huán),我們知道g1這個功能也會同樣。我們只計算這個擴展中的512個步驟,因為我們知道這個擴展會在每512步之后重復。現(xiàn)在,我們按照斐波那契案例中那樣,計算C(P(x)),除了這次是計算,需要注意,我們不在計算使用系數(shù)形式的多項式;而是根據(jù)高次單位根的連續(xù)冪來對多項式進行求值。

c_of_p需要滿足Q(x) = C(P(x), P(g1*x),K(x)) = P(g1*x) – P(x)**3 – K(x);目標是對于任何我們放入計算軌道的x(除了最后一步,因為在最后一步之后,就沒有步驟),計算軌跡中的下個數(shù)值就和之前的相等,再加上循環(huán)常量。與第1部分中的斐波那契示例不同,其中如果某個計算步驟是在k向量,下個就會是k+1向量,我們把低次單位根( g1 )的連續(xù)冪放下計算軌跡,所以如果某個計算步驟是在x = g1i ,下個步驟就會在g1i+1 = g1i * g1 = x * g1。因此,對于低階單位根( g1 )的每一個冪,我們希望最終會是P(x*g1) = P(x)**3 + K(x),或者P(x*g1) – P(x)**3 – K(x) = Q(x) = 0。因此,Q(x) 會在低次單位根 g 的所有連續(xù)冪上等于零(除了最后一個)。

# Create the composed polynomial such that # C(P(x), P(g1*x), K(x)) = P(g1*x) - P(x)**3 - K(x) c_of_p_evaluations = [(p_evaluations[(i+extension_factor)%precision] - f.exp(p_evaluations[i], 3) - constants_mini_extension[i % len(constants_mini_extension)]) % modulus for i in range(precision)] print('Computed C(P, K) polynomial')

有個代數(shù)定理證明,如果Q(x)在所有這些x坐標,都等于零,那么最小多項式的乘積就會在所有這些x坐標等于零:Z(x) = (x – x_1) * (x – x_2) * … * (x – x_n)。通過證明在任何單個的坐標,Q(x)是等于零,我們想要證明這個很難,因為驗證這樣的證明比運行原始計算需要耗費更長的時間,我們會使用一個間接的方式來證明Q(x)是Z(x)的乘積。并且我們會怎么做呢?通過證明D(x) = Q(x) / Z(x),并且使用FRI來證明它其實是個多項式,而不是個分數(shù)。

我們選擇低次單位根和高次單位根的特定排列,因為事實證明,計算Z(x),而且除以Z(x)也十分簡單:Z 的表達式是兩項的一部分。

需要注意地是,直接計算Z的分子和分母,然后使用批量模逆的方法將除以Z轉換為乘法,隨后通過 Z(X) 的逆來逐點乘以 Q(x) 的值。需要注意,對于低次單位根的冪,除了最后一個,都可以得到Z(x) = 0,所以這個計算包含其逆計算就會中斷。這是非常不幸的,雖然我們會通過簡單地修改隨機檢查和FRI算法來堵住這個漏洞,所以就算我們計算錯誤,也沒關系。

因為Z(x)可以簡潔地表達,我們也可以獲得另個好處:驗證者對于任何特別的x,可以快速計算Z(x),而且還不需要任何提前計算。對于證明者來說,我們可以接受證明者必須處理大小等于步數(shù)的多項式,但我們不想讓驗證者做同樣的事情,因為我們希望驗證過程足夠簡潔。

# Compute D(x) = Q(x) / Z(x) # Z(x) = (x^steps - 1) / (x - x_atlast_step) z_num_evaluations = [xs[(i * steps) % precision] - 1 for i in range(precision)] z_num_inv = f.multi_inv(z_num_evaluations) z_den_evaluations = [xs[i] - last_step_position for i in range(precision)] d_evaluations = [cp * zd * zni % modulus for cp, zd, zni in zip(c_of_p_evaluations, z_den_evaluations, z_num_inv)] print('Computed D polynomial')

在幾個隨機點上,進行概念檢測D(x) * Z(x) = Q(x),從而可以驗證轉賬約束,每個計算步驟是之前步驟的有效結果。但是我們也想驗證邊界約束,其中計算的輸入和輸出就是證明者所說的那樣。只是要求證明者提供P(1), D(1), P(last_step)還有D(last_step)的數(shù)值,這些都是很脆弱的;沒有證明,那些數(shù)值都是在同個多項式。所以,我們使用類似的多項式除法技巧:

# Compute interpolant of ((1, input), (x_atlast_step, output)) interpolant = f.lagrange_interp_2([1, last_step_position], [inp, output]) i_evaluations = [f.eval_poly_at(interpolant, x) for x in xs] zeropoly2 = f.mul_polys([-1, 1], [-last_step_position, 1]) inv_z2_evaluations = f.multi_inv([f.eval_poly_at(quotient, x) for x in xs]) # B = (P - I) / Z2 b_evaluations = [((p - i) * invq) % modulus for p, i, invq in zip(p_evaluations, i_evaluations, inv_z2_evaluations)] print('Computed B polynomial')

那么,我們的論證如下。證明者想要證明P(1) == input和P(last_step) == output。如果我們將I(x)作為插值,那么就是穿越(1, input)和(last_step, output)亮點的線,于是P(x) – I(x)就會在這亮點上等于零。因此,它會證明P(x) – I(x)是P(x) – I(x)的乘積,并且我們通過提高商數(shù)來證明這點。

紫色:計算軌跡多項式 (P) 。綠色:插值 (I)(注意插值是如何構造的,其在 x = 1 處等于輸入(應該是計算軌跡的第一步),在 x=g^(steps-1) 處等于輸出(應該是計算軌跡的最后一步)。紅色:P-I。黃色:在x = 1和 x=g^(steps-1)(即 Z2)處等于 0 的最小多項式。粉紅色:(P – I) / Z2。

現(xiàn)在,我們來看看將P,D和B的默克爾根部組合在一起。

現(xiàn)在,我們需要證明P,D和B其實都是多項式,并且是最大的正確階數(shù)。但是FRI證明是很大且昂貴的,而且我們不想有三個FRI證明,所以,我們計算 P,D 和 B 的偽隨機線性組合,并且基于它來進行FRI證明:

# Compute their Merkle roots mtree = merkelize([pval.to_bytes(32, 'big') + dval.to_bytes(32, 'big') + bval.to_bytes(32, 'big') for pval, dval, bval in zip(p_evaluations, d_evaluations, b_evaluations)]) print('Computed hash root')

除非所有這三個多項式有正確的低階,不然幾乎不可能有隨機選擇的線性組合,所以這很足夠。

我們想要證明D的階數(shù)小于2 * steps,而且P 和 B 的次數(shù)小于steps,所以我們其實使用了隨機的P, P * xsteps, B, Bsteps 和 D的隨機組合,并且可以看出這部分組合是小于2 * steps。

現(xiàn)在,我們來檢查下所有的多項式組合。我們先獲得很多隨機的索引,然后在這些索引上為默克爾樹枝提供多項式:

k1 = int.from_bytes(blake(mtree[1] + b'\x01'), 'big') k2 = int.from_bytes(blake(mtree[1] + b'\x02'), 'big') k3 = int.from_bytes(blake(mtree[1] + b'\x03'), 'big') k4 = int.from_bytes(blake(mtree[1] + b'\x04'), 'big') # Compute the linear combination. We don't even bother calculating it # in coefficient form; we just compute the evaluations root_of_unity_to_the_steps = f.exp(root_of_unity, steps) powers = [1] for i in range(1, precision): powers.append(powers[-1] * root_of_unity_to_the_steps % modulus) l_evaluations = [(d_evaluations[i] + p_evaluations[i] * k1 + p_evaluations[i] * k2 * powers[i] + b_evaluations[i] * k3 + b_evaluations[i] * powers[i] * k4) % modulus for i in range(precision)]

get_pseudorandom_indices函數(shù)會回復[0…precision-1]范圍中的隨機索引,而且exclude_multiples_of參數(shù)并不會給出特定參數(shù)倍數(shù)的值。這就保證了,我們不會沿著原始計算軌跡進行采樣,否則就會獲得錯誤的答案。

證明是由一組默克爾根、經(jīng)過抽查的分支以及隨機線性組合的低次證明組成:

# Do some spot checks of the Merkle tree at pseudo-random coordinates, excluding # multiples of `extension_factor` branches = [] samples = spot_check_security_factor positions = get_pseudorandom_indices(l_mtree[1], precision, samples, exclude_multiples_of=extension_factor) for pos in positions: branches.append(mk_branch(mtree, pos)) branches.append(mk_branch(mtree, (pos + skips) % precision)) branches.append(mk_branch(l_mtree, pos)) print('Computed %d spot checks' % samples)

整個證明最長的部分是默克爾樹分支,還有FRI證明,這是有更多分支來組成的。這是驗證者的實質結果:

o = [mtree[1], l_mtree[1], branches, prove_low_degree(l_evaluations, root_of_unity, steps * 2, modulus, exclude_multiples_of=extension_factor)]

在每個位置,證明者需要提供一個默克爾證明,從而讓驗證者能夠檢查這個默克爾證明,并且檢查C(P(x), P(g1*x), K(x)) = Z(x) * D(x)以及B(x) * Z2(x) + I(x) = P(x)(提醒:對于不在初始計算軌道上的x,Z(x)不會是零,所以C(P(x), P(g1*x), K(x)也不會是零)。驗證者也會檢查線性組合是正確的,然后調用。

for i, pos in enumerate(positions): x = f.exp(G2, pos) x_to_the_steps = f.exp(x, steps) mbranch1 = verify_branch(m_root, pos, branches[i*3]) mbranch2 = verify_branch(m_root, (pos+skips)%precision, branches[i*3+1]) l_of_x = verify_branch(l_root, pos, branches[i*3 + 2], output_as_int=True) p_of_x = int.from_bytes(mbranch1[:32], 'big') p_of_g1x = int.from_bytes(mbranch2[:32], 'big') d_of_x = int.from_bytes(mbranch1[32:64], 'big') b_of_x = int.from_bytes(mbranch1[64:], 'big') zvalue = f.div(f.exp(x, steps) - 1, x - last_step_position) k_of_x = f.eval_poly_at(constants_mini_polynomial, f.exp(x, skips2)) # Check transition constraints Q(x) = Z(x) * D(x) assert (p_of_g1x - p_of_x ** 3 - k_of_x - zvalue * d_of_x) % modulus == 0 # Check boundary constraints B(x) * Z2(x) + I(x) = P(x) interpolant = f.lagrange_interp_2([1, last_step_position], [inp, output]) zeropoly2 = f.mul_polys([-1, 1], [-last_step_position, 1]) assert (p_of_x - b_of_x * f.eval_poly_at(zeropoly2, x) - f.eval_poly_at(interpolant, x)) % modulus == 0 # Check correctness of the linear combination assert (l_of_x - d_of_x - k1 * p_of_x - k2 * p_of_x * x_to_the_steps - k3 * b_of_x - k4 * b_of_x * x_to_the_steps) % modulus == 0

其實還沒有完成成功;證明對跨多項式檢查和 FRI 所需的抽查次數(shù)的可靠性分析是非常棘手的。但是這些就是所有代碼,至少你不用擔心進行瘋狂的優(yōu)化。當我運行以上代碼的時候,我們會獲得STARK證明,會有300-400倍的證明成本例如,一個需要 0.2 秒的 MIMC 計算需要 60 秒來證明)。這就使得4核機器計算MIMC中的 STARK,實際上可以比后向計算 MIMC 更快。也就是說,在python語言,這會相對低效的實現(xiàn),并且這也會證明運行時間比例會不同。同時,也值得指出,MIMC 的 STARK 證明成本非常低,因為MIMC幾乎是完美地可計算,它的數(shù)學形式很簡單。對于平均計算,會包含更少的清晰計算(例如,檢查一個數(shù)是大于還是小于另一個),其計算成本可能會更高,會有大約10000-50000倍。

python求素數(shù)

python求素數(shù):

def is_prime(m):

"""判斷m是否素數(shù)"""

for i in range(2,int(m**(1/2))+1):

if m % i == 0:

return False

else:

return True

注意事項

定義一個函數(shù)并使用input進行范圍的輸入,同時將將求得的素數(shù)保存在num數(shù)組中去,便于求得在該范圍內素數(shù)的總數(shù)以及對應的具體值,同時,在本程序中并沒有對非法輸入的值進行過多的判斷,而主要就是為了實現(xiàn)功能。

注意在該函數(shù)當中,else是與內循環(huán)中的for搭配使用的,如果內循環(huán)是由break而終止的,那么else語句是不會被執(zhí)行的。

python求1~100之間的所有素數(shù)之和

解題思路:需要實現(xiàn)兩個函數(shù),一個是判斷數(shù)字是否是素數(shù);一個是求和函數(shù)。

實現(xiàn)函數(shù),判斷是否是素數(shù),is_prime,具體代碼如下:

def is_prime(num):

"""

判斷是否是素數(shù).

:param num:

:return:

"""

result = True

# 質數(shù)大于 1

if num 1:

? # 查看因子

? for i in range(2, num):

? ? ? if (num % i) == 0:

? ? ? ? ? result = False

? ? ? ? ? break

? else:

? ? ? result = True

# 如果輸入的數(shù)字小于或等于 1,不是質數(shù)

else:

? result = False

return result

實現(xiàn)函數(shù),計算數(shù)字start到end之間的所有素數(shù)之和,sum,具體代碼如下:

def sum(start, end):

"""

求閉區(qū)間[start, end]之間的素數(shù)之和.

:param start:

:param end:

:return:? ? """

result = 0;

for i in range(start, end + 1):

? if is_prime(i):

? ? ? print(i)

? ? ? result = result + i

return result

在main函數(shù)中調用求和,代碼如下:

if __name__ == '__main__':

num = 8

print(is_prime(num))

num = 5

print(is_prime(num))

print(sum(1, 5))

完整 代碼如下:

python中編程求1到100之間的素數(shù)有幾種方法?

六種。

方法一: 窮舉法

方法二: 開方減"半"法

方法三:去除偶數(shù)法

方法四:使用列表法。

方法五:素數(shù)性質法

方法六: 埃拉托斯特尼篩法

拓展資料:Python由荷蘭數(shù)學和計算機科學研究學會的Guido van Rossum 于1990 年代初設計,作為一門叫做ABC語言的替代品。Python提供了高效的高級數(shù)據(jù)結構,還能簡單有效地面向對象編程。Python語法和動態(tài)類型,以及解釋型語言的本質,使它成為多數(shù)平臺上寫腳本和快速開發(fā)應用的編程語言,隨著版本的不斷更新和語言新功能的添加,逐漸被用于獨立的、大型項目的開發(fā)。Python解釋器易于擴展,可以使用C或C++(或者其他可以通過C調用的語言)擴展新的功能和數(shù)據(jù)類型。Python 也可用于可定制化軟件中的擴展程序語言。Python豐富的標準庫,提供了適用于各個主要系統(tǒng)平臺的源碼或機器碼。2021年10月,語言流行指數(shù)的編譯器Tiobe將Python加冕為最受歡迎的編程語言,20年來首次將其置于Java、C和JavaScript之上

Python已經(jīng)成為最受歡迎的程序設計語言之一。自從2004年以后,python的使用率呈線性增長。Python 2于2000年10月16日發(fā)布,穩(wěn)定版本是Python 2.7。Python 3于2008年12月3日發(fā)布,不完全兼容Python 2。2011年1月,它被TIOBE編程語言排行榜評為2010年度語言。

由于Python語言的簡潔性、易讀性以及可擴展性,在國外用Python做科學計算的研究機構日益增多,一些知名大學已經(jīng)采用Python來教授程序設計課程。例如卡耐基梅隆大學的編程基礎、麻省理工學院的計算機科學及編程導論就使用Python語言講授。眾多開源的科學計算軟件包都提供了Python的調用接口,例如著名的計算機視覺庫OpenCV、三維可視化庫VTK、醫(yī)學圖像處理庫ITK。而Python專用的科學計算擴展庫就更多了,例如如下3個十分經(jīng)典的科學計算擴展庫:NumPy、SciPy和matplotlib,它們分別為Python提供了快速數(shù)組處理、數(shù)值運算以及繪圖功能。因此Python語言及其眾多的擴展庫所構成的開發(fā)環(huán)境十分適合工程技術、科研人員處理實驗數(shù)據(jù)、制作圖表,甚至開發(fā)科學計算應用程序。2018年3月,該語言作者在郵件列表上宣布Python 2.7將于2020年1月1日終止支持。用戶如果想要在這個日期之后繼續(xù)得到與Python 2.7有關的支持,則需要付費給商業(yè)供應商。

文章標題:python編寫函數(shù)素數(shù),Python定義函數(shù)輸出素數(shù)個數(shù)
當前鏈接:http://muchs.cn/article44/phephe.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供ChatGPT關鍵詞優(yōu)化、App開發(fā)、營銷型網(wǎng)站建設、網(wǎng)站收錄網(wǎng)站內鏈

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設