[NepCTF 2023] crypto 复现

news2024/11/25 20:20:38

 这个赛很不理想,啥都不会。

拿了WP看了几个题,记录一下

random_RSA

这题不会是正常情况,我认为。对于论文题,不知道就是不知道,基本没有可能自己去完成论文。

题目不长,只有两个菜单,共可交互8次,输入1时会随机数生成p,q,d(生成随机数左移32位再取next_prime)然后给出e(e对应的phi是(p^2-1)*(q^2-1)),输入2时会再生成p,q用e=0x10001生成c

from gmpy2 import next_prime, invert as inverse_mod
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
from random import getrandbits
from math import lcm
from sys import exit

global_bits = 1024

BANNER = rb"""
.--------.--------.--------.--------.--------.--------.--------.--------.--------.--------.--------.
| N.--.  | E.--.  | P.--.  | C.--.  | T.--.  | F.--.  | H.--.  | A.--.  | P.--.  | P.--.  | Y.--.  |
|  :/\:  |  (\/)  |  :():  |  :/\:  |  :/\:  |  :/\:  |  (\/)  |  :():  |  :/\:  |  :/\:  |  (\/)  |
|  :\/:  |  :\/:  |  ()()  |  (__)  |  :\/:  |  (__)  |  :\/:  |  ()()  |  :\/:  |  :\/:  |  :\/:  |
|  '--'n |  '--'e |  '--'p |  '--'c | '--'t  |  '--'f |  '--'h |  '--'a |  '--'p |  '--'p |  '--'y |
`--------`--------`--------`--------'--------`--------`--------`--------`--------`--------`--------`
"""


def generate_prime(bits: int):
    p = (getrandbits(bits - 32) << 32)
    return next_prime(p)


def generate_private_key(bits: int):
    p, q = generate_prime(bits), generate_prime(bits)
    n, phi = p * q, lcm(p-1, q - 1)

    d = inverse_mod(0x10001, phi)
    privateKey = RSA.construct((int(n), int(0x10001), int(d), int(p), int(q)))
    return privateKey, p > q


if __name__ == "__main__":
    print(BANNER.decode())
    print("Welcome to the world of random RSA.")
    print("Please make your choice.")
    for _ in range(8):
        choice = input()

        if choice == '1':
            p, q = generate_prime(global_bits), generate_prime(global_bits)
            N = p*q
            d = generate_prime(global_bits-32)
            e = inverse_mod(d, (p * p - 1) * (q * q - 1))
            print(f"{int(N)}")
            print(f"{int(e)}")

        elif choice == '2':
            privateKey, signal = generate_private_key(global_bits)
            Cipher = PKCS1_v1_5.new(privateKey)
            c = (Cipher.encrypt(flag.encode()))
            print(c)
            exit()

        else:
            exit()

这里菜单2没有给出p,q显然是通过前边的随机数预测。

1,ed = 1 + k(p^2-1)(q^2-1)如果分解的问题,这个关于论文也就不解释了,解释不清,解法就是通过连分式分解

\frac{e}{N^{2}-\frac{9}{4}N + 1}

结果是k,d,所以先交换取7个1和1个2然后回来慢慢处理,得到p,q,d的数组。

from gmpy2 import iroot 

def contfrac_attack(e,n):
    convergents = continued_fraction(ZZ(e) / ZZ(int(n^2 -9/4*n +1))).convergents()
    for c in convergents:
        k = c.numerator()
        d = c.denominator()
        if pow(pow(2,int(e),int(n)),int(d),n) == 2:
            phi = (e*d - 1)//k
            p_add_q = iroot(n^2+1 -phi +2*n,2)[0]
            p_sub_q = iroot(n^2+1 -phi -2*n,2)[0]
            p = (p_add_q + p_sub_q)//2
            q = n//p 
            #if p<q:
            #    p,q = q,p 
            #print('[',p,',',q,',',d,'],')
            return p,q,d


N = [data[i] for i in range(0,len(data),2)]
E = [data[i+1] for i in range(0,len(data),2)]
pqd = []
for e,n in zip(E,N):
    p,q,d = contfrac_attack(e,n)
    pqd.append([p,q,d])

2,通过MT19937来恢复random求p,q

由于给出的p,q是什么顺序未知这里需要一个爆破2^7很小

from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
from extend_mt19937_predictor import ExtendMT19937Predictor
from gmpy2 import invert,next_prime
from math import lcm 
import itertools 

bits = 1024
e = 0x10001

def gen1(bits: int):
    p = (getrandbits(bits - 32) << 32)
    return next_prime(p)

def gen2(bits: int):
    p = (predictor.predict_getrandbits(bits - 32) << 32)
    return next_prime(p)


for o in itertools.product([0,1], repeat=7):
    try:
        predictor = ExtendMT19937Predictor()
        for i,v in enumerate(pqd):
            #print(v)
            predictor.setrandbits(v[o[i]]>>32, 992) #31+31+30
            predictor.setrandbits(v[1-o[i]]>>32, 992)
            predictor.setrandbits(v[2]>>32, 960)
    except:
        continue
    
    p,q = gen2(bits),gen2(bits)
    n = p*q
    phi = lcm(p-1,q-1)
    d = invert(e, phi)
    
    privateKey = RSA.construct((int(n), int(e), int(d), int(p), int(q)))
    Cipher = PKCS1_v1_5.new(privateKey)
    try:
        flag = (Cipher.decrypt(c,'\x00'))
        print(flag)
    except:
        continue 

#b'NepCTF{c4e4356067fb3bedc53dde7af59beb1c}'

对于用PKCS1打包的RSA还要用它来解,并且题上用咱就用咱lcm(p-1,q-1)和(p-1)*(q-1)不相等。

MT19937在填入数据的时候,如果重复部分有误会报错,这时候应该就是p,q的顺序不正确了。这题一共得到644组32位随机数有20组,比624多20组这样,在这里通过的后边都正确,但是有几组在后边生成时并未用到,所以有多组相同的解

 recover

这题作一半卡了,脑子有点晕了,没看到提示flag的格式。

from math import ceil
from hashlib import md5

from Crypto.Util.number import *

#from secret import key, flag
key = b'bfaxctvpacpfxsrljavvvmsi'
flag = b'flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}'

def MD5(x): return md5(x).hexdigest()


assert (len(flag) == 58)
assert (len(key) == 24)

P = [[0, 2, 3, 4, 5, 6],
     [1, 4],
     [0, 3],
     [0, 3, 4, 5],
     [0, 1, 2, 3, 4, 7],
     [2, 3, 4, 5, 6],
     [0, 1, 2, 3],
     [1, 2, 3, 4, 5, 7],
     [8, 12, 13, 14],
     [8, 11, 12, 13, 15],
     [9, 12, 15],
     [11, 13, 15],
     [8, 9, 10, 12, 13, 15],
     [8, 9],
     [11, 13, 14],
     [10],
     [16, 19, 20],
     [16, 18, 19, 20, 21],
     [16, 17, 18, 19],
     [17, 18, 20, 22, 23],
     [17, 19, 23],
     [17, 18, 20, 21, 23],
     [16, 18, 20, 21, 22, 23],
     [16, 17, 18, 20, 21, 22, 23],
     [25, 26, 29, 31],
     [25, 26],
     [26, 28, 30],
     [27, 28, 29, 30, 31],
     [25, 29],
     [25, 26, 30, 31],
     [28, 29, 30, 31],
     [24, 26, 29, 31],
     [35, 36, 39],
     [33, 35, 38],
     [33, 35, 37, 39],
     [32, 33, 34, 35, 37, 38],
     [32, 33, 34, 35, 37, 39],
     [35, 38],
     [33, 34, 38, 39],
     [33, 34, 39],
     [41, 42, 43, 44, 47],
     [40, 41, 42, 45, 47],
     [41, 42, 45, 47],
     [40, 43, 44, 46],
     [41, 46, 47],
     [41, 42, 43, 44, 46, 47],
     [41, 42, 44, 45],
     [40, 41, 42, 45, 46],
     [48, 50, 51, 52, 53, 54, 55],
     [48, 49, 50, 52, 53, 54, 55],
     [49, 55],
     [48, 49, 50, 51, 52, 54],
     [52, 53],
     [48, 49, 53, 54, 55],
     [48, 49, 52, 55],
     [48, 49, 51, 52, 55],
     [58, 59],
     [56, 61, 63],
     [57, 63],
     [56, 59, 60],
     [61, 63],
     [57, 58, 61, 62, 63],
     [57, 58],
     [60, 62]]


def enc(v, keys, le):
    t = v
    for i in keys:
        q = []
        for j in P:
            tmp = 0
            for k in j:
                tmp ^= t[k]
            q.append(tmp)
        t = [int(q[j]) ^ int(i[j]) for j in range(le)]
    return t


keys = []
for i in range(len(key)//8):
    l = bytes_to_long(key[i*8:i*8+8])
    m = bin(l)[2:].zfill(8*8)
    keys.append([int(i) for i in m])

fb = bin(bytes_to_long(flag))[2:].zfill(ceil(len(flag)/8)*8*8)

ciphertext = ""
for i in range(0, len(fb), 64):
    t = enc([int(j) for j in fb[i:i+64]], keys, 64)
    ciphertext += "".join([str(j) for j in t])

print(ciphertext)
cipher = '11101100100000110101100101100001100111011100100111000000010110000110011011000100110101110111010000100100001100010011001100010100101000110001011101000000100010101000000110000110011110001101110110110111000000100010011011011011101011101000000000100010000101001110100101011000001110010000000000100110001101110011111010001100101101111010101111101110100110101010011010011010101110100001001101100110010000010000011100100101111010010000011001000110000100110111100010101011000100100111010000101010110110001010110101111111'
print(cipher)

这里P有64组数据,很显然每8个一组,可以看成m*A=c的运算,由于key有24字节,这个运算共进行了3次,也就是对一个字符 ((m*A+key1)*A + key2)*A+key3对一个字节这样加密以后,key可能是多组的。

由于给出了flag的格式flag{...}58个字符前补0成64个分8*8,这样按列每组都给了一两个明文,其它明文提示是小字字母(想错了),所以很容易爆破出一组key来。用这个key求出其它字符。每次改一下idx就能求出一列数据,后来有几组出不来,发现不只是小写字母。说是爆破其实量极小,秒出的那种。

idx = 4
v0 = [0,0,0,0,0,0,ord('f'),ord('l')]
tp = P[idx*8: idx*8+8]
tP = [[i-idx*8 for i in t] for t in tp]
print(tP)
for v1 in 'l':
    for v in 'h':
        vs = get_v(v0[idx],ord(v1), ord(v))
        cs = [ciphers[idx], ciphers[idx + 8], ciphers[idx + 16]]
        key0 = get_key(vs,cs, tP)
        if key0 == False:
            continue
        print('Try:', idx, v1, v)
        for i in range(8):
            ok = False
            for v2 in tab:
                t = enc([int(i) for i in bin(ord(v2))[2:].zfill(8)], key0, 8, tP)
                if all(int(ciphers[idx + i*8][j])==t[j]  for j in range(8)):
                    ok = True 
                    print(i,v2)
            if not ok:
                break
        else:
            print(f'key {idx}', key0)
   

'''
000000fl
ag{flag_
is_the_r
eadable_
key_whos
e_md5_st
arts_wit
h_3fe04}
'''
#flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}

然后第2步卡了,这里说flag是可读的且md5头是这个。这里一时没想到flag的格式,所以每组可能的key有100多组,8组就有巨多,就没法弄了。后来看WP,原来提示的那一句在这里用。如果真正的key也是有flag{...}格式的话,那的提示的有6组,爆破就没几个了。

每求出每组key的组合

def get_int(aa):
    return [int(''.join(map(str, a)),2)for a in aa]
    
def get_list(k1,k2,k3):  
    return [[int(i) for i in bin(ord(a))[2:].zfill(8)] for a in [k1,k2,k3]]    
    
def get_key2(vs,cs,tP):
    keys = [BitVec(f'key_{i}',1) for i in range(24)]
    key_arr = [keys[i:i+8] for i in range(0,24,8)]
    print(vs)
    print(cs)
    print(tP)
    s = Solver()
    s.add(keys[0] == 0)
    s.add(keys[8] == 0)
    s.add(keys[16] == 0)
    for v,c in zip(vs,cs):
        t = enc(v, key_arr,8, tP)
        for i,tk in enumerate(t):
            s.add(tk == int(c[i]))
    
    allkey = []
    while s.check() == sat:
        d = s.model()
        rkey = [d[keys[i]].as_long() for i in range(24)]
        rkey_arr = [rkey[i:i+8] for i in range(0,24,8)]
        #print(rkey_arr)
        tmp = get_int(rkey_arr)
        if all(0x20<=v<0x7f for v in tmp):
            allkey.append(tmp)
            
        condition = []
        for i in range(24):
           condition.append(keys[i] != rkey[i])
        s.add(Or(condition))
        
    return allkey 

flag = b'flag{flag_is_the_readable_key_whose_md5_starts_with_3fe04}'
vs = [0]*6 + [v for v in flag]
#print(vs)

tab = string.ascii_lowercase 
tabs = list('flag{') + [tab]*18 + ['}']
print(tabs)
for idx in range(8):
    tp = P[idx*8: idx*8+8]
    tP = [[i-idx*8 for i in t] for t in tp]
    tv = [[int(i) for i in bin(vs[j*8 + idx])[2:].zfill(8)] for j in range(8)]
    tc = [ciphers[idx + j*8] for j in range(8)]
    allkey = []
    for k1 in tabs[idx]:
        for k2 in tabs[idx+8]:
            for k3 in tabs[idx+16]:
                key0 = get_list(k1,k2,k3)
                for i,v2 in enumerate([vs[i*8+idx] for i in range(8)]): 
                    t = enc([int(i) for i in bin(v2)[2:].zfill(8)],key0, 8, tP)
                    if int(ciphers[idx + i*8],2) == int(''.join(map(str,t)),2):
                        allkey.append(k1+k2+k3)
    
    print(list(set(allkey)))  

然后对这些爆破,然后眼工找到一组能读的。

k = [
['fcw', 'fdo', 'fef'],
['lnd', 'lxn', 'lev'],
['asz', 'are', 'aqi', 'apv'],
['gan', 'gkj', 'gnf', 'gtr', 'gdb'],
['{ok', '{qy', '{bx'],
['cbk', 'ahm', 'ygt', 'joe', 'lio', 'tir', 'arr', 'jxc', 'ypr', 'vnm', 'yjm', 'ldv', 'agi', 'cor', 'nat', 'hre', 'gng', 'ppe', 'vct', 'esg', 'nvr', 'rba', 'lsp', 'pgc', 'tsm', 'tfv', 'vyk', 'tqp', 'vvo', 'pjz', 'vai', 'ajp', 'cum', 'rug', 'lqm', 'nci', 'nyv', 'jmx', 'apo', 'yhp', 'vlp', 'juz', 'aet', 'rwz', 'eix', 'hpx', 'hec', 'tko', 'nlm', 'jwg', 'hjg', 'rzc', 'cxt', 'cwp', 'tdk', 'gve', 'rox', 'eke', 'gya', 'eqz', 'cmo', 'yei', 'phg', 'vtr', 'yro', 'czi', 'nnp', 'hhz', 'rme', 'gac', 'eda', 'lkr', 'glz', 'lfk', 'gtx', 'nto', 'prx'],
['kjy', 'hqr', 'qpb', 'tyf', 'vrs', 'tsi', 'cht', 'mxv', 'wbm', 'pfd', 'lhh', 'qzm', 'gqn', 'wdu', 'osc', 'xbq', 'aov', 'ept', 'fap', 'mry', 'yro', 'oyl', 'pjs', 'bre', 'cnl', 'dfr', 'raf', 'tuq', 'cdc', 'nir', 'qvz', 'ytw', 'whb', 'rmq', 'evl', 'sqx', 'uix', 'ikc', 'wnz', 'fmg', 'ueo', 'dje', 'aey', 'lnp', 'xnf', 'zes', 'fgh', 'ain', 'igt', 'ucw', 'bxj', 'nee', 'hwj', 'lbg', 'mta', 'zid', 'jph', 'aca', 'noj', 'ial', 'vtk', 'rki', 'kfn', 'zck', 'plk', 'jzg', 'xdi', 'kla', 'jvp', 'gwv'],
['zr}', 'pf}', 'xw}', 'rc}']]

from hashlib import md5

v =[0]*8
for v[0] in k[0]:
  for v[1] in k[1]:
    for v[2] in k[2]:
      for v[3] in k[3]:
        for v[4] in k[4]:
          for v[5] in k[5]:
            for v[6] in k[6]:
              for v[7] in k[7]:
                key = ''.join(''.join(r[i] for r in v) for i in range(3))
                m = md5(key.encode()).hexdigest()
                if m.startswith('3fe04'):
                    print(key, m)

#flag{hardertorecoverkey}
'''
flag{aapcnsabjcfwdznxpa} 3fe042d564d4e19a99c18038e95a4923
flag{npxcxsnovlwwnzfkrk} 3fe044e1e71f56918db24bc143cbdd02
flag{chrcxsnqmwcwnzfyoj} 3fe045110e1506d003ae582f22ce3d6c
flag{gsrcxpnbtqcwnvfxxx} 3fe044fcc37311bc71e76987e341ee16
flag{ycrcxptopncwnvrkrl} 3fe049dcd66d48a19f824ed9dfd51ae2
flag{vxrceraocncwvenktf} 3fe0477ae63f44db4e5657ae34b71f8e
flag{yrpcepkbrkfwvvjxoi} 3fe040c7d8ff041d0784e93b952f206a
flag{gvxdxsdqytwonzbyak} 3fe043b101bbbec84b04027f4872e6a5
flag{rwzdxpnobbronvfkam} 3fe04ea7bc9169f9565730a5786a767b
flag{hardertorecoverkey} 3fe0442d2939da2767c07fe4b735a917
flag{gczenstoldrfdzrkzc} 3fe04b78470cb999ecce16590b5a2a04
flag{nfpexsnqnmffnzfypg} 3fe04a6cce75c141462498c92e7517bf
flag{afpeesdbjgffvzbxph} 3fe04500376029ba4432e8af5d79b00b
'''           

后边两个恩格码机的题,第1个是基于明文不出现在密文中,比如明文第5位是A则密文中第5位一定不是A。

第二个基于某个论文。跳过。

secureAgg

这个题目很长,如果能有时间认识读题就能答。

AggServer.py

from Crypto.Util.number import *
from User import User

class AggServer:

    def __init__(self,mbits):
        self.N=8
        self.g=2
        self.p=0x9f785dd75d97d7dea66a89a038e7c880b962e526fa9d0f14639de8d82b953fbf0e01739495df3d5fdb189aa079c70e9cc49c7390c2fd3166d91fe8b511f918a7
        self.mbits=mbits
        self.users=[ User(mbits,i) for i in range(self.N)]
        self.M=getPrime(mbits+self.N.bit_length()+1)
        self.params=(self.g,self.p)
    
    def genKeys(self):
        for u in self.users:
            u.genKey(self.params)
        for u in self.users:
            u.agree(self.users,self.params[1])
    
    def get_enc_list(self):  #泄露
        enc_list=[]
        for u in self.users:
            enc_data=u.get_enc_data(self.M)
            enc_list.append(enc_data)
        return enc_list
    
    def aggregate(self):   #生成key
        self.key=sum([ u.data for u in self.users])%self.M
        return self.key
    
    def update(self):
        for u in self.users:
            u.update_data(self.key)

    def system_info(self):
        info = ""
        info += "System params: \n"
        info += f"g={self.params[0]}\np={self.params[1]}\nM={self.M}\n"
        info += "User pubkeys: \n"
        info += f"pubkeys={str([ u.pub for u in self.users])}\n"
        return info

chall.py

# !/usr/bin/env python
from Crypto.Util.number import *
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from base64 import b64encode
from FLAG import flag
from AggServer import AggServer
import socketserver
import os, sys, random
import signal, string

ROUNDS=20
BANNER=br'''
            Welcome to my Secure Aggregation System.
    If you can pass my 20 rounds of agg testing, I'll give you flag~
                        Have fun! 
'''


class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()

    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass

    def recv(self, prompt=b'> '):
        self.send(prompt, newline=False)
        return self._recvall()

    def close(self):
        self.request.close()

    def handle(self):
        signal.alarm(180)

        self.send(BANNER)
        self.send(b"Generating parameters...")
        agg=AggServer(114)
        agg.genKeys()
        self.send(agg.system_info().encode())

        try:
            for i in range(ROUNDS):
                self.send(f'#Round {i+1}'.encode())
                enc_list=agg.get_enc_list()
                self.send(f"enc_list={enc_list}".encode())
                key=agg.aggregate()
                message=''.join(random.sample(string.ascii_letters,16))
                aes_key=sha256(str(key).encode()).digest()[:16]
                aes=AES.new(aes_key,AES.MODE_CBC,iv=bytes(range(16)))
                enc=aes.encrypt(pad(message.encode(),16))
                self.send(f"enc={b64encode(enc)}".encode())
                inp=self.recv(b"input your message: ").decode()
                if inp==message:
                    self.send(b'Correct!')
                else:
                    self.send(b'Error!')
                    exit(0)
                agg.update()
            self.send(flag)
        except:
            self.send(b'wtf?')
        self.close()


class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
    pass


if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 12345
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    server.serve_forever()


usr.py

from Crypto.Util.number import *

class PRG:
    def __init__(self,seed):
        self.state=seed
        self.a=114514
        self.b=1919810
        self.kbits=seed.bit_length()
        self.bits=[]
    
    def gen(self):
        self.state=(self.a*self.state+self.b)&((1<<self.kbits)-1)
        bin_arr=list(map(int,bin(self.state)[2:].zfill(self.kbits)[::-1]))
        self.bits.extend(bin_arr)

    def randbits(self,n):
        while len(self.bits)<n:
            self.gen()
        output=self.bits[:n]
        self.bits=self.bits[n:]
        return int(''.join(map(str,output)),2)


class User:

    def __init__(self,mbits,id):
        self.mbits=mbits
        self.id=id
        self.data=getRandomNBitInteger(mbits)

    def genKey(self,params):
        g,p=params
        self.priv=getRandomRange(1,p)
        self.pub=pow(g,self.priv,p)

    def agree(self,users,p):
        self.agreement_keys={}
        for u in users:
            if u.id!=self.id:
                u_pub=u.pub
                k=pow(u_pub,self.priv,p)
                self.agreement_keys.update({u.id:k})
    
    def get_enc_data(self,M):
        enc=(114*self.data+514)%M
        for id,k in self.agreement_keys.items():
            if id>self.id:
                enc+=PRG(k).randbits(self.mbits)%M
            elif id<self.id:
                enc-=PRG(k).randbits(self.mbits)%M
        return enc
    
    def update_data(self, key):
        mask=(1<<self.mbits)-1
        noise=getRandomNBitInteger(16)
        self.data=(self.data ^ key ^ noise) & mask

chall.py给了一个交互的服务,如果正确20次就给flag

先成成Agg,然后每一轮都先给出 enc_list=agg.get_enc_list(),这个函数调用users

    def get_enc_list(self):  #泄露
        enc_list=[]
        for u in self.users:
            enc_data=u.get_enc_data(self.M)
            enc_list.append(enc_data)
        return enc_list

users里的加密是个非常小的LCG

    def get_enc_data(self,M):
        enc=(114*self.data+514)%M
        for id,k in self.agreement_keys.items():
            if id>self.id:
                enc+=PRG(k).randbits(self.mbits)%M
            elif id<self.id:
                enc-=PRG(k).randbits(self.mbits)%M
        return enc

显然,这里组出enc_data 求data只需要 (sum(enc_data)-514*8)*114^-1 % M,最后在有key的情况下求AES就行了。

最后一个关于DES的太长了,没看,说是很简单。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/878184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot 在 redis 中使用 BloomFilter 布隆过滤器机制

一、导入SpringBoot依赖 在pom.xml文件中&#xff0c;引入Spring Boot和Redis相关依赖 <!-- Google Guava 使用google的guava布隆过滤器实现--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><vers…

IPv4分组

4.3.1 IPv4分组 IP协议定义数据传送的基本单元——IP分组及其确切的数据格式 1. IPv4分组的格式 IPv4分组由首部和数据部分&#xff08;TCP、UDP段&#xff09;组成&#xff0c;其中首部分为固定部分&#xff08;20字节&#xff09;和可选字段&#xff08;长度可变&#xff0…

行业追踪,2023-08-14

自动复盘 2023-08-14 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

深入浅出 栈和队列(附加循环队列、双端队列)

栈和队列 一、栈 概念与特性二、Stack 集合类及模拟实现1、Java集合中的 Stack2、Stack 模拟实现 三、栈、虚拟机栈、栈帧有什么区别&#xff1f;四、队列 概念与特性五、Queue集合类及模拟实现1、Queue的底层结构&#xff08;1&#xff09;顺序结构&#xff08;2&#xff09;链…

做海外游戏推广有哪些条件?

做海外游戏推广需要充分准备和一系列条件的支持。以下是一些关键条件&#xff1a; 市场调研和策略制定&#xff1a;了解目标市场的文化、玩家偏好、竞争格局等是必要的。根据调研结果制定适合的推广策略。 本地化&#xff1a;将游戏内容、界面、语言、货币等进行本地化&#…

计算两个字符串之间的编辑距离【支持多字节字符串】

/*** 计算两个字符串之间的编辑距离【支持多字节字符串】** param string $str1 求编辑距离中的其中一个字符串* param string $str2 求编辑距离中的另一个字符串** return int*/ function levenshtein_copy(string $str1, string $str2): int {$arr1 mb_str_split($str1);$ar…

IK分词器升级,MySQL热更新助一臂之力

ik分词器采用MySQL热更新 ​ 官方所给的IK分词器只支持远程文本文件热更新&#xff0c;不支持采用MySQL热更新&#xff0c;没关系&#xff0c;这难不倒伟大的博主&#xff0c;给哈哈哈。今天就来和大家讲一下如何采用MySQL做热更新IK分词器的词库。 一、建立数据库表 CREATE…

20个常考的前端算法题,你全都会吗?

现在面试中&#xff0c;算法出现的频率越来越高了&#xff0c;大厂基本必考 今天给大家带来20个常见的前端算法题&#xff0c;重要的地方已添加注释&#xff0c;如有不正确的地方&#xff0c;欢迎多多指正&#x1f495; 1、两数之和 题目&#xff1a;给定一个数组 nums 和一…

d3dcompiler43.dll缺失怎么修复?dll缺失解决方法分享

在使用电脑过程中&#xff0c;我们有时会遇到一些系统文件的问题&#xff0c;其中一个常见的问题是d3dcompiler43.dll文件的损坏或丢失。当这个文件出现问题时&#xff0c;可能会导致应用程序无法正常运行或图形渲染出现异常。最近我也遇到了这个问题&#xff0c;以下是我修复d…

ClickHouse(十八):Clickhouse Integration系列表引擎

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…

UE4拾取物品高亮显示

UE4系列文章目录 文章目录 UE4系列文章目录前言一、如何实现 前言 先看下效果&#xff0c;当角色靠近背包然后看向背包&#xff0c;背包就会高亮显示。 一、如何实现 1.为选中物品创建蓝图接口 在“内容” 窗口中&#xff0c;鼠标右键选择“蓝图”->蓝图接口&#xff0c…

P13-CNN学习1.3-ResNet(神之一手~)

论文地址:CVPR 2016 Open Access Repository https://arxiv.org/pdf/1512.03385.pdf Abstract 翻译 深层的神经网络越来越难以训练。我们提供了一个残差学习框架用来训练那些非常深的神经网络。我们重新定义了网络的学习方式&#xff0c;让网络可以直接学习输入信息与输出信息…

乐鑫ESP32S3串口下载出现奇怪问题解决方法

正在学习ESP32S3&#xff0c;有一个原厂BOX开发板&#xff0c;使用虚拟机&#xff0c;安装 debian11 &#xff0c;安装IDF4.4.5版本工具。下载box示例代码。 进入example,idf.py set-target esp32s3, idf.py flash 下载时&#xff0c;出现错误&#xff1a; Wrote 22224 bytes…

【Unity实战系列】如何把你的二次元老婆/老公导入Unity进行二创并且进行二次元渲染?(附模型网站分享)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;在正式开始讲主线知识之前&#xff0c;我们先来讲点有趣且有用的东西。 我知道&#xff0c;除了很多想从事游戏开发行业的人以外&#xff0c;还…

试岗第一天问题

1、公司的一个项目拉下来 &#xff0c;npm i 不管用显示 后面百度 使用了一个方法 虽然解决 但是在增加别的依赖不行&#xff0c;后面发现是node版本过高&#xff0c;更换node版本解决。 2、使用插件动态的使数字从0到100&#xff08;vue-animate-number插件&#xff09; 第一…

Redis之删除策略

文章目录 前言一、过期数据二、数据删除策略2.1定时删除2.2惰性删除2.3 定期删除2.4 删除策略比对 三、逐出算法3.1影响数据逐出的相关配置 总结 前言 Redis的常用删除策略 一、过期数据 Redis是一种内存级数据库&#xff0c;所有数据均存放在内存中&#xff0c;内存中的数据可…

Python 图形界面框架TkInter(第八篇:理解pack布局)

前言 tkinter图形用户界面框架提供了3种布局方式&#xff0c;分别是 1、pack 2、grid 3、place 介绍下pack布局方式&#xff0c;这是我们最常用的布局方式&#xff0c;理解了pack布局&#xff0c;绝大多数需求都能满足。 第一次使用pack&#xff08;&#xff09; import …

大模型相关知识

一. embedding 简单来说&#xff0c;embedding就是用一个低维的向量表示一个物体&#xff0c;可以是一个词&#xff0c;或是一个商品&#xff0c;或是一个电影等等。这个embedding向量的性质是能使距离相近的向量对应的物体有相近的含义&#xff0c;比如 Embedding(复仇者联盟)…

湖南大学计算机考研分析

关注我们的微信公众号 姚哥计算机考研 更多详情欢迎咨询 24计算机考研|上岸指南 湖南大学 湖南大学计算机考研招生学院是信息科学与工程学院。目前均已出拟录取名单。 湖南大学信息科学与工程学院内设国家示范性软件学院、国家保密学院和湘江人工智能学院&#xff0c;计算机…

软件测试基础之软件缺陷处理

一、什么是缺陷 不满足用户确定需求、影响软件功能实现的问题、故障 缺陷就是人们通常所说的bug。 ex.一下哪一种选项不属于软件缺陷___。 A.软件没有实现产品规格说明所要求的功能 B.软件中出现了产品规格说明不应该出现的功能 C.软件实现了产品规格说明没有提到的功能 D.软…