[HITCON CTF 2022] Superprime,rev Meow_way,BabySSS格基约减法,Secret共模攻击模未知

news2024/11/16 12:00:42

目录

Superprime

Reverse Meow_way

BabySSS

Secret


Superprime

这个题5层RSA加密,很简单就是要带条件爆破5组p,q,一开始看错了,对为5组是一一对应的,回头发现后边两对不是对应的。

from Crypto.Util.number import getPrime, isPrime, bytes_to_long


def getSuperPrime(nbits):
    while True:
        p = getPrime(nbits)
        pp = bytes_to_long(str(p).encode())
        if isPrime(pp):
            return p, pp


p1, q1 = getSuperPrime(512)  #ok
p2, q2 = getSuperPrime(512)  
p3, q3 = getSuperPrime(512)
p4, q4 = getSuperPrime(512)
p5, q5 = getSuperPrime(512)

n1 = p1 * q1
n2 = p2 * p3 #明显很小,不是 p2*q2是p2*q3
n3 = q2 * q3
n4 = p4 * q5
n5 = p5 * q4

e = 65537
c = bytes_to_long(open("flag.txt", "rb").read().strip())
for n in sorted([n1, n2, n3, n4, n5]):
    c = pow(c, e, n)

print(f"{n1 = }")
print(f"{n2 = }")
print(f"{n3 = }")
print(f"{n4 = }")
print(f"{n5 = }")
print(f"{e = }")
print(f"{c = }")

对三种情况对应3种爆破姿势。

数据部分,方便哪们想复现的话可以用。hitcon的题目会放到googleapis上,但这个地址对国内极不稳定,明通明不通

n1 = 132240475872174910020944408159013384770525986234801028624784519134365862704105251340824787510945183963356820885920367304711310957365047441178683686926111455575911962257698539064559510444855775549001648292058855493337857073693460061212792795075263084221929517773754699732129582794061997056827998985829666251060653380798686353779510948629280009197715644814616657550158740378670095210797455828266323922570838468050733341304227070902756780052159113811360169205531739117518635829837403006788948761106892086004133969899267757339921
n2 = 95063555614573541810575593850289506856925979977609991181205616159125089261546784721154599484613262518469706157215924537125160406418217535531993036958388330505871763176297570429533467696205928686731756713059807727405313286020007347211892135226632724359291407913539632339885950358476265995466145680878334722001
n3 = 59077122528757446350604269162079270359932342538938986760275099248290981958441838384256597839386787448447136083450980256330743221155636885358548541847176342745397373638152767362253944731433134474562146358334422503033973244936835557423934491676324297243326613498319086748647812745223753746779568080090592100960499863677438403657325762852705171109382084916335379889394829715777901290096314487661584614712488781379507151355301063123233880909931925363322846957197537676660047824476129446066149857051131731840540157488590899311381370266592295206055792990886734933291304077440476730373491475852882163732120626849448728573574411786320772125534383707413572678316508826450778346723441956945169297689138799298561759843280317867927205551400065163199599457
n4 = 24589423756497058585126900932611669798817346035509889383925628660158156567930038333401661451846451875869437263666365776498658699865323180836374906288949824205543130261556051807217164348291174483234810669420041361857307271050079366739157441129916338485838528114129985080841445467007786565727910355311119650431197742495274527401569906785121880408809802492383216836691265423297722021017515667257863302820657924121913047547741420413553737917632809270380269758313556777803344394624408862183672919570479289614998783678080936272369083
n5 = 185885020243714550225131939334004568560534422416697599024696590344782893162219788079305752632863387855011040772104676488940707663157284194641170875157382507202789029285286466326803699701161968587945867047101502048926016515139728368809523009828247173096909917611001113266938209226483162533302629909322412013492978440863258135181226831155024690292336026753678424906151360739424148666951389956182136072508650529271179749569637083537783283360860102371562796635391549934474381821125255176073752645643893294533330184238070085333427
e = 65537
c = 44836759088389215801662306050375432910426695023654894661152471598197009644316944364461563733708795401026569460109604554622161444073404474265330567406370705019579756826106816505952084633979876247266812002057927154389274998399825703196810049647324831928277737068842860115202258059693760003397831075633707611377854322143735834890385706873765241863615950449707047454133596389612468366465634011925228326638487664313491916754929381088396403448356901628825906815317934440495749705736715790281606858736722493438754469493049523175471903946974639097168758949520143915621139415847104585816466890751841858540120267543411140490236193353524030168152197407408753865346510476692347085048554088639428645948051171829012753631844379643600528027854258899402371612

from Crypto.Util.number import getPrime, isPrime, bytes_to_long,long_to_bytes 
from gmpy2 import invert, iroot 

def getSuperPrime(nbits):
    while True:
        p = getPrime(nbits)
        pp = bytes_to_long(str(p).encode())
        if isPrime(pp):
            return p, pp

第1种,最简单,因为q = bytes_to_long(str(p)),p,q是相关的可以直接爆破,原先经常用的是2进制的,现在这个是10进制的,就乘pow(10,i)

#1,
#n1 = p1 * q1
def get_sq(n, l):
    p = 0
    for i in range(l,-1,-1):
        for j in range(9,-1,-1):
            sp = p + j*pow(10, i)
            sq = bytes_to_long(str(sp).encode())
            if sp*sq<= n:
                p = sp 
                print("", i, j)
                break 
    print(p)
    return p

p1 = get_sq(n1, 220)
#p1 = 8146548592442976266345996123132853490697005499246649457977706700220974227149533573761967281334961993159106889103915430835029497970085237349414587895387361
q1 = bytes_to_long(str(p1).encode())

对于n2,n3来说由于p,q并不对应,所以这里从后向前爆破,正好通过n3尾部判断。如果没有这人实际上只通过n2尾部的话是不能爆破的,有数不清的组合。

从后爆破的话还有一个问题,就是不足位时前被0,但如果是最后一位就不再被0,所以这里对小的做了能分解直接退出,避免无法判断的补0出现。

#2,
#n2 = p2 * p3
#n3 = q2 * q3
def get_tail(p2,p3, idx):
    print(f"{idx}\n{p2=}\n{p3=}")
    tn2 = p2*p3 
    if tn2>n2:
        return False
    if p2>1 and n2%p2 == 0:
        print(f"OK\n{p2=}\n{n2//p2}")
        exit()
    for i in range(10):
        for j in range(10):
            tp2 = p2+i*pow(10,idx)
            tp3 = p3+j*pow(10,idx) 
            if str(tp2*tp3)[-(idx+1):] == ('000'+str(n2))[-(idx+1):]:
                if idx == 154:
                    print('x', str(tp2*tp3)[-(idx+1):], ('000'+str(n2))[-(idx+1):])
                #爆到的 idx 字节 * 8 位 与n3 比较
                sq2 = bytes_to_long(str(tp2).zfill(idx+1).encode())
                sq3 = bytes_to_long(str(tp3).zfill(idx+1).encode()) #当不足时补0,当足时补0错
                mask = (1<<((idx+1)*8))-1
                if ((sq2*sq3)^n3) & mask == 0:
                    #print(hex(mask), tp2,tp3)
                    get_tail(tp2,tp3, idx+1)

get_tail(0,0,0)
p2 = 8896291584885417569104339023688932443326753617531842711599106401724528341937087331194574622599888534531753509912922572906401573640791655490141830263538581
q2 = bytes_to_long(str(p2).encode())
p3 = 10685750878049478986600454022422733804784834227531623991827538970867377925593354382775253050419846972347584519245766235538419501021140939003899401773087821
q3 = bytes_to_long(str(p3).encode())

第3种由于p4*q5没有尾部特征,只能从头开始爆破。需要判断上下边界,即后部全0大于n和后部全9小于n的情况剪掉。

#n4 = p4 * q5
#n5 = p5 * q4
def get_45(p4,p5,idx):
    if idx<0:
        return False
    if idx<153 and (p4==0 or p5 == 0):  #154-155位10进制
        return False
    if p4>1 and n4%p4 == 0:
        print(f'OK\n{p4 = }\np5 = {long_to_bytes(n4//p4)}')
        exit()
    #print(idx,p4,p5)
    q4 = bytes_to_long(str(p4).encode())
    q5 = bytes_to_long(str(p5).encode())
    if p4*q5 > n4 or p5*q4 > n5:
        #print('>')
        return False 
    if idx>0:
        sp4 = str(p4).encode()[:-idx]+b'9'*(idx)
        sp5 = str(p5).encode()[:-idx]+b'9'*(idx)
        #if idx<2:
        #    print(idx,sp4,sp5)
        rp4 = int(sp4)
        rp5 = int(sp5)
        rq4 = bytes_to_long(sp4)
        rq5 = bytes_to_long(sp5)
        if idx<154 and p4>0 and p5>0 and (rp4*rq5<n4 or rp5*rq4<n5):
            #print(f"{idx} ,{rp4} ,{rp5} , {rq4}, {rq5}, {n4}, {n5}, {p4*rq5<n4}, {p5*rq4<n5}")
            return False
    
    for i in range(10):
        for j in range(10):
            #print('>>>>>',idx,i,j)
            tp4 = p4+i*pow(10,idx-1)
            tp5 = p5+j*pow(10,idx-1) 
            get_45(tp4,tp5, idx-1)

#get_45(0,0,155)
p4 = 6759224678814800913204473280361658486772650199941114505283409645622497866148765146601841353932633241398607040792961131806556756943022446601137737571037341
p5 = 11868750061342011267437975338788313730068511026231254554820987614699325962867540061083226545014725808842166519144882448332395484715124334891963558447955747
q4 = bytes_to_long(str(p4).encode())
q5 = bytes_to_long(str(p5).encode())
#print(n4%p4, n5%p5)

最后是5个已经分解n的RSA按从大到小顺序解密

d1 = invert(e, (p1-1)*(q1-1))
d2 = invert(e, (p2-1)*(p3-1))
d3 = invert(e, (q2-1)*(q3-1))
d4 = invert(e, (p4-1)*(q5-1))
d5 = invert(e, (p5-1)*(q4-1))

#加密顺序 2,1,5,4,3
m = pow(pow(pow(pow(pow(c,d3,n3),d4,n4),d5,n5),d1,n1),d2,n2)
print(long_to_bytes(m))
#b"hitcon{using_different_combinations_of_primes_still_doesn't_make_this_bad_prime_generation_method_any_safer...}"

Reverse Meow_way

这个题一看就用了复杂的东西。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4; // [esp+0h] [ebp-24h]
  int v5; // [esp+0h] [ebp-24h]
  int v6; // [esp+14h] [ebp-10h]
  int v7[2]; // [esp+18h] [ebp-Ch] BYREF

  v7[0] = -1;
  v7[1] = -1;
  if ( argc < 2 )
  {
    sub_401340("Usage: %s <flag>\n", (char)*argv);
    exit(1);
  }
  if ( strlen(argv[1]) != 48 )
  {
    sub_401340("Wrong length\n", v4);
    exit(1);
  }
  v6 = (int)argv[1];
  dword_40544C(v6, v6 >> 31, v6, v6 >> 31, 196, 0, v7, (int)v7 >> 31);
  ++v6;
......
  dword_4053F4(v6, v6 >> 31, v6, v6 >> 31, 152, 0, v7, (int)v7 >> 31);
  dword_405438(v6 + 1, (v6 + 1) >> 31, v6 + 1, (v6 + 1) >> 31, 101, 0, v7, (int)v7 >> 31);
  v5 = memcmp(&unk_405018, argv[1], 0x30u);     // 将0x30依次修改为1,2,...仅判断1个字节,爆破得到flag
  if ( v5 )
  {
    sub_401340("Wrong\n", v5);
    exit(-1);
  }
  sub_401340("I know you know the flag!\n", 0);
  return 0;
}

用了48个函数,和参数,每个函数又都是指针,还被隐藏了。

不过最后有个问题memcmp对全部进行比较,这里如果将0x30改为1,他就仅对第1个字符比较。这样通过修改比较的长度就可以实现爆破了。

这个字节在0x401bf5在文件里的偏移是0xff5

后来看了别人的帖子,这里用push 0x33;retf将32位转64位执行,可惜没有get到出题人的用心。

import subprocess

data = list(open('meow_way.exe', 'rb').read())

flag = ''
for i in range(1, 0x31):
    fname = f'meow_{i}.exe'
    data[0xff5] = i 
    open(fname, 'wb').write(bytes(data))
    for v in range(0x21, 0x7f):
        tmp = (flag+chr(v)).ljust(0x30, '0')
        rc,out= subprocess.getstatusoutput(f"{fname} {tmp}") 
        if 'I know you know the flag!' in out:
            flag += chr(v)
            print(flag)
            break            

print(flag)
#hitcon{___7U5T_4_S1mpIE_xB6_M@G1C_4_mE0w_W@y___} 提交不正确,把两头的下划开线删掉
#hitcon{7U5T_4_S1mpIE_xB6_M@G1C_4_mE0w_W@y}  

BabySSS

看到一个大牛博客 ,里边有3道,说是后两道以后上,关注中。

这个题我用的crt方法,他还提到格基约减法。

M = \begin{bmatrix} 1 & 1 & ... & 1 & 1 & & ... & \\ x_{1} & x_{2} & ... & x_{8} & & 1 & & \\ ... & ... & ... & ... & ... & ... & ... & ...\\ x_{1}^{128} & x_{2}^{128} & ... & x_{8}^{128} & & & 1 & \\ -y_{1} & -y_{2} & ... & -y_{8} & & & & 1 \end{bmatrix}

由于并没有取模,只是限制在64位,所以把右部单位阵的1部分改为2^-63 

然后进行约减,结果中前8位为0的行对应的值再乘2**63就得到对应的一组v

#LLL法
V = matrix(QQ, 130,8+130)
for i in range(8):
    for j in range(129):
        V[j,i] = pow(a[i][0], j)
    V[129,i] = -a[i][1]

for i in range(129):
    V[i, 8+i] = pow(2, -63)
V[129,8+129] = 1

k = V.LLL()
#前8位全0的行
v = k[1][8:-1]*9223372036854775808  #2**63

Secret

看上去挺简单,就是个共模攻击,由于共模攻击时可以两边共同除其中一项m^(p+e1) / m^(p+e0) = m^(e1-e0) 所以这里的p可以解决掉。

麻烦的就是模未知。

“取一组核空间的基构成的矩阵,在这个矩阵上进行LLL算法即可得到符合条件的小系数 k_{i} 。因为我们不能求逆,把正负号分两边进行计算,即可得到n的整数倍 K_{n} , 利用多组这样的倍数求一个最大公倍数即可恢复n。” 一时没理解,原样复制。

from output import es,cs

B = matrix(ZZ, 2, 64)
B[0] = es 
B[1] = [1 for _ in range(64)]

M = B.right_kernel_matrix()
L = M.LLL()

#求n
def compute_kn(coff):
    res_right = 1
    res_left = 1
    for i ,cof in enumerate(coff):
        if cof > 0:
            res_right = res_right * cs[i]**cof
        else:
            res_left = res_left * cs[i]**(-cof)
    return res_left - res_right

n = compute_kn(L[0])
#再求公约数
for l in L[1:]:
    n = gcd(compute_kn(l),n)
    n = factor(n,limit = 2**20)[-1][0]
    if n.nbits() <= 2048:
        break
print(n)

得到n后先处理一下p,然后用共模攻击

n = 17724789252315807248927730667204930958297858773674832260928199237060866435185638955096592748220649030149566091217826522043129307162493793671996812004000118081710563332939308211259089195461643467445875873771237895923913260591027067630542357457387530104697423520079182068902045528622287770023563712446893601808377717276767453135950949329740598173138072819431625017048326434046147044619183254356138909174424066275565264916713884294982101291708384255124605118760943142140108951391604922691454403740373626767491041574402086547023530218679378259419245611411249759537391050751834703499864363713578006540759995141466969230839

from Crypto.Util.number import *
mpe1_inv = inverse(cs[0],n)
_es = [e-es[0] for e in es[1:]]       # _c = m^(e1-e0)
_cs = [c*mpe1_inv%n for c in cs[1:]]  # 

#找两个互素的e进行共模攻击 find gcd(_ei,_ej) = 1
find = False
for i in range(len(_es)):
    for j in range(len(_es)):
        if gcd(_es[i],_es[j]) == 1:
            find = True
            break
    if find:
        break
print(i,j)

e1,e2 = _es[i] , _es[j]
c1,c2 = _cs[i] , _cs[j]
g, x1, x2 = xgcd(e1,e2)
m = pow(c1,x1,n)*pow(c2,x2,n) % n
print(long_to_bytes(int(m)))
#hitcon{K33p_ev3rythIn9_1nd3p3ndent!}

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

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

相关文章

[附源码]Python计算机毕业设计Django旅游度假村管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

计算程序运行时间:计算或者不计算sleep()的两种情况perf_counter()和process_time()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 计算程序运行时间&#xff1a; 计算或者不计算sleep()的两种情况 perf_counter()和process_time() [太阳]选择题 对下面描述错误的选项为&#xff1f; import time print(使用perf_counter…

[附源码]计算机毕业设计作业管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Matplotlib绘制图像大全】(二十四):Matplotlib为图像添加网格信息

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

Mybatis练习(多条件查询)

Mybatis练习(多条件查询) 概述 功能实现的步骤&#xff1a; 编写接口方法 参数&#xff1a;所有查询条件结果&#xff1a;List 在映射配置文件中编写SQL语句 编写测试方法并执行 编写接口方法 在 BrandMapper 接口中定义多条件查询的方法。 而该功能有三个参数&#xf…

排序算法两万字总结(C语言实现)

文章目录前言一、排序的概念二、常见的排序算法排序实现的接口(1)插入排序基本思想1.直接插入排序1.1代码实现1.2直接插入排序特性总结2.希尔排序(缩小增量排序)2.1代码实现2.2希尔排序的特性总结(2)选择排序基本思想1.直接选择排序1.1代码实现1.2直接选择排序的特性总结2.堆排…

Sentinel服务保护

一&#xff0e;微服务雪崩问题&#xff1f; 微服务模块之间相互调用&#xff0c;因为调用(同步调用)链中的一个服务故障&#xff0c;引起整个链路都无法访问的情况 解决方案: 避免服务宕机&#xff1a;流量控制服务已经宕机&#xff1a;熔断降级Hystrix -----springcloud …

python中numpy创建数组

1. numpy数组的创建 1.1 使用array方法进行创建 数组是numpy中一种常见的格式&#xff0c;和列表类似&#xff0c;可以理解为矩阵&#xff0c;可以使用array方法进行获取 import numpy as np import random#使用numpy生成数组,得到ndarray的类型 t1 np.array([1,2,3,]) pri…

[附源码]计算机毕业设计springboot小太阳幼儿园学生管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

CMake 官方文档入门

对比官方文档练习 step1 基本起始点 一个基本的项目&#xff1a;从源文件构建可执行程序 文件目录如下 编写 CMakeLists.txt 如下&#xff1a; # cmake 要求的最小版本 cmake_minimum_required(VERSION 3.24) # 设置项目名称 可以设置版本号 project(Tutorial VERSION 1.0)…

【Docker】本地镜像与私有库:发布、拉取,图文展示全过程

Docker是基于Go语言实现的云开源项目。Docker的主要目标是**“Build&#xff0c;Ship and Run Any App,Anywhere”**。也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理&#xff0c;使用户的APP&#xff08;可以是一个WEB应用或数据库应用等等&#xff09;及其运…

Linux环境MySQL数据库主从复制保姆级教程

文章目录1、环境准备1.1、安装MySQL1.2、设置root登录密码2、主库配置2.1、修改my.cnf2.2、重启数据库2.3、检验设置是否成功2.4、建立主从复制的账号3、从库配置3.1、配置my.cnf3.2、配置复制参数3.3、查看从库状态4、测试5、注意事项5.1、接口放行5.2、防火墙关闭5.3、Slave_…

Android Framework的框架描绘~

前言 写在前面&#xff1a; 1、有没有必要学习linux内核&#xff1f; 我认为是很有必要的。学习linux内核有助于我们加深对一些概念的理解&#xff0c;比如“进程”、“线程”。 2、有没有必要自己编译android源码&#xff1f; 非必须&#xff0c;可以直接用android studio查看…

【图表利剑】开发复杂Echarts时,visualMap视觉组件中属性seriesIndex必须用起来

一、背景 据说90%的可视化是用Echarts开发&#xff0c;没错&#xff0c;笔者也没例外&#xff0c;在新的开发项目中&#xff0c;遇到了这个开发神器Echarts&#xff0c;想要的功能就是在省份上显示动态效果图&#xff0c;比如涟漪。原来的功能已有范围视觉组件visualMap。 二…

【Matplotlib绘制图像大全】(十九):Matplotlib绘制等高线

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

SAP ABAP——数据类型(四)【TYPE系列关键字】

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

gitHub不能用密码推送了,必须要使用令牌

有一段时间没使用github去push项目了&#xff0c;今天push之后&#xff0c;根据提示输入账号密码&#xff0c;但是失败了&#xff0c;报错如下&#xff1a; support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com…

【Swin Transformer原理和源码解析】Hierarchical Vision Transformer using Shifted Windows

目录前言一、动机和改进点二、整体架构&#xff1a;SwinTransformer三、输入设置&#xff1a;PatchEmbed四、4个重复的Stage&#xff1a;BasicLayer4.1、SwinTransformerBlock4.1.1、创建mask4.1.2、shift特征4.1.3、为shift后的特征划分窗口4.1.4、W-MSA VS SW-MSA4.2、PatchM…

Android APP 停止运行报错弹窗

一个APP经常性的报错,然后就会弹出一个"很抱歉,xxx已停止运行"这样的弹窗,在Android系统层临时将这个弹窗屏蔽.弹窗如下: 在没做过此类修改之前,不知到如何下手的情况下,请做如下几步: 在Android目录下全局搜索关键字"很抱歉",然后会有一个路径frameworks…

ICS计算系统概论实验3—LC3汇编代码实现最长重复子字符串Longest-duplicate-substring

Lab03 Longest-duplicate-substring Purpose 子字符串是字符串中至少出现一次的连续字符序列。重复子字符串是一种由相同字符组成的子字符串。例如&#xff0c;“aabbbc”的重复子字符串是“aa”&#xff0c;“bbb”和“c”。 给定一个字符串及其长度&#xff0c;计算出它最长…