ezRSA

part 1

#part1
p = getPrime(512)
q = getPrime(512)
n = p * q
phi = (p-1) * (q-1)
d = getPrime(250)
e = inverse(d, phi)
c = pow(bytes_to_long(parts[0]), e, n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}') # n = 124695452995031270645183837267530422032624508784074534979189655228220709056309638648794696369835930482818980808128467814617220810217534821336503942838791498456112882717378013827550680516551959078234339477401303759763506487676709408813412867364414651706461400252466842182365340612883444737530603407481042520627
# e = 38587713366842463962841747677614707312145479235042165803103947138237921458583509748629042842505955223421671992698976799249425980974893271454942323501453571320592126625468760278770909411858284131095166550317734018153286242950401311537208914820833671566620645882329390747892971373265592565291598852744678229891
# c = 75650426098322108299742769179799276679353245586432433359812352366165787480762021753671012472067826915659840541954505167382050569833945309043431554352347482992118091659840982421987700648585142917347916194810259117115753813661282178558428786374835684668840019166776178494086580424196110694158066034697988927644

容易发现

\[\frac{1}{3}n^{\frac{1}{4}} > d
\]
\[\min(p, q) < \max(p, q) < 2\min(p, q)
\]

因此采用 \(\text{Wiener's Attack}\)。

part 2

#part2
p = getPrime(80)
q = getPrime(80)
n = p * q
e = 2
c = pow(bytes_to_long(parts[1]), e, n)
print(f'n = {n}')
print(f'c = {c}')
print(f'p,q = {p,q}') # n = 649329048322675374317593820985753646586809799201
# c = 283668420132846011615755415362202578109404366325
# p,q = (647260709632957671018359, 1003195526406802286444839)

发现 \(e = 2\) 且 \(p, q\) 较小,采用 \(\text{Rabin}\) 算法。

part 3


#part3
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
c = pow(bytes_to_long(parts[2]), e, n)
print(f'n = {n}')
print(f'c = {c}')
print(f'p^q = {p^q}') # n = 85836893651204560884454211125508692415276042143801480450535044733242333318334455339451808653755272841343378345709375676280488068099971805717946097641116078266013229365158341178806480395974457905053516603153056936745020102883744430977333247681929718298626185526512756702624513738698825219177049538628421559753
# c = 75578834548096799626696300881096262997184146142305165096930004492293642496308047534319034721187289042138332386120962890635270628767192988167590315544321566944902760623837249074921079890026503778053466720161607743010204269544291059577848021218234039433294700788160167294093796603060247381385159054508170520277
# p^q = 5068548570505625142069285468439450186210992627026138517591800598908379828953823253346928574075223127205617451260708785889033493211347183583859669806824864

\(p \oplus q\) 已知,考虑从低到高搜索 \(p, q\) 的每一位,对于当前为 \(i\) 满足异或后第 \(i\) 位与 \(p \oplus q\) 相等,且 \(p \times q \le n\),实现剪枝。

part 4

#part4
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 3
m = bytes_to_long(os.urandom(32)+parts[3])
c = pow(m, e, n)
print(f'n = {n}')
print(f'c = {c}')
print(f'mleak = {m>>128}') # n = 136909292741753142871542219643510188168311518562065789353531367466023357011784735447560466352669948897633633920102617017949126915203615330337196942328793619163571419292670395849251337340787480297972818664454785647844715189207055430597030032696044932960884594660634280475822683286430432169515120767378120972393
# c = 14763067643592454478187771324072634160297758439803081056226124797870386993054732731754324146768654813122274647054179017048620683751626439261028839186682159969656271385676822426489416369402998625865982105676257668946313225156476831065481561281126267398712822218497384996243578386630794573662378684549962709522
# mleak = 287621732882458207416007037901690948810437972193283953524078189541847647258

明文 \(m\) 的高 \(\text{bit}\) 位已知,低 \(128\) 位未知,根据 \(\text{Coppersmith}\) 定理可求。

ezNumberTheory

part 1

p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
gift = pow(p+q,q,n)-p
m = bytes_to_long(flag[:part_len])
c = pow(m,e,n)
print("n =",n)
print("gift =",gift)
print("c =",c)

已知

\[(p+q)^q - p \equiv gift (\text{mod } n)
\]
\[n=pq
\]

考虑二项式展开得到

\[\sum_{i=0}^{q} \binom{q}{i} {p}^{i} {q}^{q-i} - p \equiv gift (\bmod pq)
\]

化简得

\[p^q + q^q - p \equiv gift (\text{mod } pq)
\]

不妨考虑拆分模数 \(pq\),得到两个式子。

\[q^q \equiv gift (\text{mod } p)
\]
\[p^q - p \equiv gift (\text{mod } q)
\]

由于 \(p, q\) 为质数,由费马小定理可得

\[q^q\equiv gift (\text{mod } p)
\]
\[0 \equiv gift (\text{mod } q)
\]

对 \(gift\) 因式分解得到 \(q\),进而 \(p = \frac{n}{q}\)。

已知 \(e,p,q\),可求出密文 \(m\)。

part 2

p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
m = bytes_to_long(flag[part_len:2*part_len])
gift = pow(n-1,m,n**2)
c = pow(m,e,n)
print("n =",n)
print("gift =",gift)
print("c =",c) # n = 101825028937892274755066568298675753051915211984336844010001051946487425488926444636462308770518438066690807207349397829434761111870976777194195377994066094978667372161712559828354279213717904934626695765400184018995342438568172381388749973725572499090794995578069624189552411881722996041605959223833931977161
# gift = 10368336518202599155478611962986419931032852827247241544520944151147424100095888793813818133261771295138537638975002709013348196763698154979511238402220870231916534915445557931918512473116396709289462544729254616655147690181935999744990349056920271954901882532521970967307761055252723712876050094383313331140406445004997917905258680326374893836686879404331037481540004243801858344196072242572121743245711481444665694028492376994909442739868671793792049626000877294534619734785195159330183197692177383792865340479971388526007871832995878259364333594949083550807440342049213394072558604884076160696389453987350453566282
# c = 6206002756473719752481539026703107851866702754011241324450943403363532188346664095512595594879972008741307201868011790850666619709952602312346601585431717191460826191100496612662950423560204126590072745286069584415447406165328489464592884522745095517397118876988652114937810284710552486235169949976593170616

已知

\[(n-1)^m \equiv gift (\text{mod }n^2)
\]

不妨先考虑

\[(n-1)^m \equiv gift (\text{mod }n)
\]

同上,有

\[(-1)^m \equiv gift (\text{mod }n)
\]

带入 \(gift, n\) 可得

\[1 \equiv gift (\text{mod }n)
\]

于是 \(m\) 为偶数。

直接展开原式有

\[\sum_{i=0}^{m} \binom{m}{i} (-1)^{i} {n}^{m-i} \equiv gift (\text{mod }n^2)
\]

化简得

\[(-1)^{m-1}nm + (-1)^m \equiv gift (\text{mod }n^2)
\]

\[1 - nm \equiv gift (\text{mod }n^2)
\]

求得

\[nm \equiv n^2 - gift + 1 (\text{mod }n^2)
\]

根据第一部分 \(m\) 的大小推断 \(m,n\) 大小接近,试除后发现 \(m = \frac{n^2 - gift + 1}{n}\) 恰为整数,故 \(m\) 为所求值。

part 3

p = getPrime(512)
q = next_prime(p)
r = getPrime(512)
n = p * q
e = 65537
m = bytes_to_long(flag[2*part_len:])
gift = (pow(1+m*n,1,n**2)*pow(r,n,n**2))%(n**2)
print("n =",n)
print("gift =",gift)
print("p =",p)
print("q =",q) # n = 120085278656547434097495160698983440086977117014813250068332400723955573086081539793659925690983763612644098938270646361630753175121916904514302168476109276991065963359696653413330575343172587757112308794397643577457876878076258704713342584783867357600427211623403743168388707834963362860793081706620920977197
# gift = 755365096368274234067764643236574524026724653923904235465391689910808113641191521577417355583242717443863451427293486428108305560959934240539916731737071269870765365812729624798503913486014927177398814766178335408644263304959990001131184599054858122656321624816269434361664736002888774514548687701448375859895656340630928111228145226768972365422917506757004452665088879334351527814068349598913876771933729841797767944898598495453091334481416909244894797229851139025287531257727280929467263018600829848751441007477417666581057493947789435287529403836954674188989033519154270698877075630430517874818318137411379414838

已知

\[(nm + 1)r^n \equiv gift (\text{mod } n^2)
\]

考虑

\[(nm + 1)r^n \equiv gift (\text{mod } n)
\]

\[r^n \equiv gift (\text{mod } n)
\]

再考虑将 \(n\) 分解有

\[r^n \equiv gift (\text{mod } p)
\]
\[r^n \equiv gift (\text{mod } q)
\]

由费马小定理有

\[( r^{q} )^{p} \equiv gift (\bmod p)
\]

\[r^q \equiv gift (\text{mod } p)
\]

考虑欧拉定理 \(a^n \equiv a^{n \text{ mod } \varphi(p)} (\text{mod p})\) 有

\[r^{q \bmod \varphi(p)} \equiv gift (\bmod p)
\]
\[r^{q \bmod (p - 1)} \equiv gift (\bmod p)
\]

记 \(q^{-1}\) 为 \(q\) 模 \(p - 1\) 的逆元,可知

\[( {r} ^ {q \bmod (p - 1)} ) ^ {q ^ {-1}} \equiv gift ^ {q ^ {-1}} (\text{mod } p)
\]
\[{r} ^ {q {q} ^ {-1} \bmod (p - 1)} \equiv gift ^ {q ^ {-1}} (\text{mod } p)
\]

\[r \equiv {gift} ^ {q ^ {-1}} (\text{mod } p)
\]

由于 \(r\) 与 \(p\) 大小相近,可解出唯一 \(r\)。

回到原式,记 $ ( r^n ) ^ {-1} $ 为 \(r^n\) 模 \(n^2\) 的逆元,有

\[nm + 1 \equiv gift \times (r ^ n) ^ {-1} (\bmod n ^ 2 )
\]
\[nm \equiv gift \times (r ^ n) ^ {-1} - 1 (\text{mod } n ^ 2 )
\]

依旧有 $ m = \frac{(gift \times (r ^ n) ^ {-1} - 1) \text{ mod } n ^ 2 }{n} $,此题完。

ezPwntools

挺过了前面的分P狂魔,单题可以开始轻松了不少。

import random
from Crypto.Util.number import *
from typing import Callable
with open("flag.txt", "r") as f:
flag = f.read().strip() length = 128 class LCG:
def __init__(self, length=128):
self.length = length
self.setparam() def setparam(self):
self.m = getPrime(length+1)
self.a = getPrime(length)
self.b = getPrime(length)
self.seed = random.randint(0, self.m - 1)
self.begin = self.seed def generate(self):
for i in range(10):
self.seed = (self.a * self.seed + self.b) % self.m
seed_list = []
for i in range(5):
self.seed = (self.a * self.seed + self.b) % self.m
seed_list.append(self.seed)
return seed_list def __call__(self):
return self.begin def challenge(input:Callable[[str],None], print:Callable[[str],None]):
print("Welcome to TSCTF-J! If you can recover the seed, you will get the flag!")
for i in range(512):
lcg = LCG()
print("Here is your gift:{}".format(lcg.generate()))
i = input(f"Give me the seed: ")
if int(i) != lcg():
print(f"Oh, you are wrong!")
return
print(f"Congurations!{flag}")

观察到 generate 函数每次做 \(15\) 次线性同余变换并返回最后 \(5\) 次结果,可以列出方程。

\[x_{i+1} \equiv ax_i + b (\text{mod } m)(i = 1,2,3,4)
\]

考虑相邻两项相减消去 \(b\) 有

\[x_5 - x_4 \equiv a(x_4 - x_3)(\text{mod } m)
\]
\[x_4 - x_3 \equiv a(x_3 - x_2)(\text{mod } m)
\]

则对于 \(a\) 有

\[a \equiv \frac{x_5 - x_4}{x_4 - x_3} \equiv \frac{x_4 - x_3}{x_3 - x_2}(\text{mod } m)
\]

交叉相乘可得

\[(x_5 - x_4)(x_3 - x_2) \equiv (x_4 - x_3)^2 (\text{mod } m)
\]

不难发现

\[m \mid (x_5 - x_4)(x_3 - x_2) - (x_4 - x_3)^2
\]

取出上式的最大质因子即可得到 \(m\),接着易于得到 \(a, b\) 的值。

然后解 \(10\) 次一元线性同余方程

\[x_{i-1} \equiv (x_i - b)a^{-1}(\text{mod } m)
\]

对于 \(512\) 次操作,求出 \(m, a, b\),并解出其初值,用 pwntools 与交互库交互即可。

如下是一份代码

from pwn import *
from gmpy2 import *
from sympy import *
con = remote('challenges.hazmat.buptmerak.cn', 21747)
t = con.recvline() for _ in range(512):
t = con.recvline()
t = t[19:len(t)-1]
ls = t.split()
xi = []
for i in ls:
xi.append(int(i[:len(i)-1]))
x1, x2, x3, x4, x5 = xi
m = gmpy2.gcd((x5-x4)*(x3-x2)-(x4-x3)**2, (x4-x3)*(x2-x1)-(x3-x2)**2)
while is_prime(m) == False:
div = primefactors(m)
m //= div[0]
a = (x5 - x4) * gmpy2.invert(x4 - x3, m) % m
b = (x5 - a * x4) % m
x = x1
for i in range (10, -1, -1):
x = (x - b) * gmpy2.invert(a, m) % m
t = con.recv()
print(_ + 1)
con.sendline(str(x))
t = con.recv()
print(t)

ezECC

#sage
from Crypto.Util.number import *
from sage.all import *
msg = b'???'
flag = b'TSCTF-J{'+msg+b'}'
m = bytes_to_long(flag)
(p,a,b) = (getPrime(len(bin(bytes_to_long(flag)))) for i in range(3))
E = EllipticCurve(GF(p),[a,b])
for i in range(4):
print(E.random_point())
e = 114514
K = E.lift_x(m+1)
eK = e*K
print(f"eK={eK}") # (121542556343240612458886464797113519174471159973947349739843570016310276547868092596053087152046638137671892191449161589255393370014868931365353180578227117593735, 98840327394835055943257602264613388284774639725847294267402852043945104193135363216749971927532657727021952911622427228151863672295675502233797082353097959401869)
(99873546068894326234875062311058443230105529641172112880280159410919160848811689840010700811925066814781044568587853533466146854172381759747204462070834544581290, 54021704113721739503680080012966661376438637715420865450114718929076757346120207862947548620569435334895396324086781218017455445315421875871714429627637052871264)
(157617948261622464254152314994703598559915540865514420750304511730242939622181332932412360735409968696715108030369878546783001121709970056186086411214753185288604, 172554749510163658517336910991986476106096485848063383199885085041705448141288872247307505628175707155625972718684398442883637022240936050198926361252214588735919 )
(35601692031837010013294196210817440996871532774395053520652383520080490377765688796593595849840043210266473831404618732851470643297944496494254634489110294026906, 83109137089012676168973029782730032714034653700896174331183408691033951856596721848482516578501834370646437639802694578133409539742068584938899820955422945845189 )
# eK=(148943471114336569351357302344843611917995236697008317506292328720097140911033713257363114040728547610446354966023690433690295644571622343830380563979394775174929, 5570936030363753742907439216925560949272269404612411400083981446597152991432704283038752432067099389895408182978262946903003923985122728700021027170168725851130 )

构式题,椭圆曲线密码,做法与 ezNumberTheoryezPwntools 完全一样。

给定域 \(GF(p)\),椭圆曲线 \(E_p: y^2 = x^3 + ax + b\) 上任意 \(4\) 点 \(A_1,A_2,A_3,A_4\),与 \(e\) 倍基点 \(K(m+1, y_{lift\_x})\),\(eK\) 的坐标,求 \(m\)。

对于点 \(A_i(x_i, y_i)\) 有

\[y_i^2 \equiv x_i^3 + ax_i + b (\text{mod } p)
\]

一样是先消去 \(b\),用 \(a\) 联立两个方程得到 \(p\),然后解出 \(a, b\)。

利用 sage 自带的求椭圆曲线阶的函数 E.order(),求得阶为 \(P\),这个题就转化为了:

\(K\) 为椭圆曲线 \(E_p\) 上一点,已知 \(eK\),\(e\),求 \(K\)。

求出 \(e\) 关于阶 \(P\) 的逆元即可。

ezFakekey

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from typing import Callable
with open("flag.txt", "r") as f:
flag = f.read().strip() def pad(data):
pad_len = 16 - len(data) % 16
return data + bytes([pad_len] * pad_len) def unpad(data):
pad_len = data[-1]
return data[:-pad_len] def generate_key():
return get_random_bytes(32) def generate_iv():
return get_random_bytes(16) def encrypt(message, key, iv):
assert len(key) == 32
assert len(iv) == 16
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(message))
return ciphertext def decrypt(ciphertext, key, iv):
assert len(key) == 32
assert len(iv) == 16
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext))
return plaintext def challenge(input:Callable[[str],None], print:Callable[[str],None]):
print("Welcome to TSCTF-J! If you are Administrator, I will give you a flag!")
key = generate_key()
iv = generate_iv()
while True:
print('[E]ncrypt the message')
print('[D]ecrypt the message')
print('[G]et the flag')
print('[Q]uit')
option = input('> ').upper()
if option == 'E':
input_message = input('Plz input your message: ')
m = input_message.encode()
if b'Administrator' in m:
print('Permission denied!')
return
ciphertext = encrypt(m, key, iv)
print(f'Your ciphertext: {ciphertext.hex()}')
elif option == 'D':
ciphertext = bytes.fromhex(input('Plz input the ciphertext: '))
m = ciphertext
plaintext = decrypt(m, key, iv)
print(f'Your plaintext: {plaintext}')
elif option == 'G':
ciphertext = bytes.fromhex(input('Plz input the ciphertext: '))
m = ciphertext
plaintext = decrypt(m, key, iv)
if b'Administrator' in plaintext:
print(f'Congurations!Here is flag:{flag}')
return
else:
print('Permission denied!')
elif option == 'Q':
return
else:
print('Unknown option:', option)

又是我们的交互题,这是一道 AES-CBC 的已知文本攻击题目,我们需要构造一条密文,使得密文经过解密后出现一条子串 Administrator

由于 CBC 加密只有相邻的两个块有异或关系,我们可以先通过加密得到含有 administrator 的循环密文,其循环节为 \(16\)(CBC加密的块大小),找到对应字节所在块的位置,进行遍历搜索解密。

考虑 AES 编码只存在十六进制数,因此找到一个十六进制两位数对其做替换解密,直到出现子串 Administrator,即是我们所需要的密文,最后发现替换第 \(72,73\) 位可以做到。

代码如下(非预期解)

from pwn import *
from gmpy2 import *
from sympy import *
con = remote('challenges.hazmat.buptmerak.cn', 21815)
ls = [b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f']
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recv()
con.sendline("E")
t = con.recv()
t = b'administrator' + b'\x03' * 3 + b'administrator'+ b'\x03' * 3 + b'administrator'
con.sendline(str(t))
t = con.recv()
Administ = t[17:]
Administ = Administ[:len(Administ) - 1]
for i in ls:
for j in ls:
A = Administ
ad = A[:72] + i + j + A[74:]
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recv()
con.sendline("D")
t = con.recv()
c = str(ad, "utf-8")
con.sendline(c)
t = con.recvline()
ans = t[20:]
if (b'Administrator' in ans):
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recvline()
t = con.recv()
con.sendline("G")
t = con.recv()
con.sendline(str(c))
t = con.recv()
print(t)
break

Conclusion

对于新生赛而言,题目难度是比较高的,\(8\) 题里面我只做了 \(5\) 题(在此期间和 ACM 队友去集训了一天,不然可能还能做一道题),甚至不乏有 ezECC 这种题目解法与其他题目完全重合的这种题,同时也见识到了各种密码题的解题思路,收益还是比较大的,虽然我想学密码学的原因有一部分是数学,但我希望不要所有的密码题都是数学,ezRSA 中对搜索的考察就是很不错的一点。

成就:在比赛期间快把 NanachiPYthok 烦死了(不会做题导致的),现在其实也是什么都不会呐,还是任重而道远啊。

TSCTF-J2024 密码向WP(5/8)的更多相关文章

  1. WordPress用户导入Drupal7并登录

    用户导入比较简单.使用Feeds模块中的Feeds Import工具就行. 不过有个不好地方的,导入前密码是明文,导入后该模块会自动转换为Drupal加密后的密码. 这需要导入后原wp的用户也能登录d ...

  2. hackthebox通关手记(持续更新)

    简介: 花了点时间弄了几道题目.以前我是用windows渗透居多,在kali linux下渗透测试一直不怎么习惯.通过这几天做这些题目感觉顺手多了.有些题目脑洞也比较大,感觉很多也不适合于实际的环境 ...

  3. WP 手机Lumia 820 锁屏密码的破解研究

    Windows Phone lumia 手机锁屏密码的破解研究     大家好今天给大家分享一个最新研究案例, 近日笔者接Nokia Lumia 820, 由于客户密码失误太多,导致锁屏23000余分 ...

  4. 实验吧—密码学——WP之 古典密码

    首先我们研究题目 1.古典密码 2.key值的固定结构 3.加密方式就在谜面里 首先看到这些数字我们就能想到ASCII,而且做题多了就能看出123是{:125是},所以得到字符串如下 OCU{CFTE ...

  5. 实验吧—密码学——WP之 传统知识+古典密码

    仔细读题,发现有价值的信息: 几个不同的年份:“+甲子”:key值结构 首先我们并不知道这些年份在这里代表着什么,那么我们就去百度一下发现了如下所示的六十甲子顺序表 而在表中每个年份前都有数字,将他们 ...

  6. Bugku-不可破译的密码[wp]

    一 题目分析 flag.txt cipher.txt (1)密码表形式和维吉尼亚密码一样 (2)看到504Q0304 很容易想到 504B0304 Zip文件头. 二 解题步骤 2.1 解密密文 根据 ...

  7. Android,ios,WP三大手机系统对比

    从前,我以为.一个手机系统只是一个系统的UI风格,没什么不同的.然而,在我混合使用这三个手机系统之后,才明白,一个手机系统远不只一个UI那么简单,而真的是可以称之为一个“生态”. 首先祭出三台经典设备 ...

  8. 【WP开发】加密篇:双向加密

    说起双向加密,如果以前在.NET开发中弄过加/解密的朋友都不会陌生,常用的算法有DES.AES等.在RT应用程序中,也提供了加密相关的API,算法自然是一样的,只是API的封装方式不同罢了,因为RT不 ...

  9. wp手机 htc x310e

    入手htc x310e 手机不错,用着流畅 不习惯,已升到wp7.8,系统限制还是有些需要的功能没有,比如说短信拦截什么的 我需要的常用软件少 转手了 1 注销windows live? 设置--应用 ...

  10. MySQL数据库忘记root密码解决办法

    MySQL数据库忘记root密码解决办法 1.在运行输入services.msc打开服务窗体,找到MYSQL服务.右键停止将其关闭.如图:

随机推荐

  1. EXlucas

    \(EXLucas\) 扩展卢卡斯定理 ·题意 试求: \[C^{m}_n \mod P \ \ \ \ \ \ \ \ \ \ \ ( P \in N ^* ) \] 注意, \(P\) 非质数( ...

  2. 低版本安卓home assistant网页浏览器

    试了很久 一直有问题的一点 , 使用普通浏览器加载不出来登录界面 只能加载出icon 然后就没反应了 考虑到了webview的问题 但是没想到安卓5.0之前是固定且不可升级的webview 从 And ...

  3. FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生

    ​自从互联网普及之后,用于视频直播的流媒体技术就发展起来.这几十年中,比较有影响的主要有MMS.RTSP.RTMP.HLS.SRT.RIST几种,分别介绍如下. 1.MMS协议 MMS全称Micros ...

  4. Mongodb入门5

    最近在用MongoDBKoa2做个小项目,记录一下: 首先,如何连接线上数据库: const url = `mongodb://user:pwd@ipaddr:27017/Blog`; const m ...

  5. ASP.NET Core – ADO.NET

    前言 自从用 Entity Framework 就再也没有用过 ADO.NET 了. 很多年前写过 基础 ADO.NET 访问MYSQL 与 MSSQL 数据库例子. 今天刚好想做个单侧, 那就顺便翻 ...

  6. ASP.NET Core 单元测试

    前言 单元测试是好, 但是也很花时间. 有些功能封装好了以后也不怎么会再打开, 所以通常就是徒手测试一下, 过了就过了. 但是往往就是那么神奇, 就是会有需求漏掉. 后来要加, 又由于不想潜水, 对自 ...

  7. MyBatisPlus——标准数据层开发

    标准数据层开发 标准数据层CRUD功能 lombok 一个java类库,提供了一组注解,简化POJO实体类开发    常用注解@Data    为当前实体类在编译期设置对应的get/set方法,无参/ ...

  8. ConcurrentLinkedQueue详解(图文并茂)

    前言 ConcurrentLinkedQueue是基于链接节点的无界线程安全队列.此队列按照FIFO(先进先出)原则对元素进行排序.队列的头部是队列中存在时间最长的元素,而队列的尾部则是最近添加的元素 ...

  9. Docker基本概念(LXC?镜像、容器、仓库是什么?容器和虚拟机又是什么?)(一)

    学习Docker前,我们有必要了解下Docker的前生LXC(Linux Container). 一.LXC介绍 LXC 可以提供轻量级的虚拟化,用来隔离进程和资源,和我们传统观念中的全虚拟化完全不一 ...

  10. Maya 2019.2 Mtoa 无法正常加载并报错

    事件起因: 在开始安装 Maya2019.2 时自动安装的 Mtoa 的版本为 5.3.1,但是在插件管理器里无法启用插件,于是乎去网上下了一个低的版本 5.1.1,虽然可以使用但是渲染出来的东西不能 ...