加密与安全_探索非对称加密算法_RSA算法

文章目录

  • Pre
  • 主流的非对称加密算法
  • 典型算法:RSA
  • Code
  • RSA的公钥和私钥的恢复
  • 小结

在这里插入图片描述


Pre

加密与安全_探索密钥交换算法(Diffie-Hellman算法) 中我们可以看到,公钥-私钥组成的密钥对是非常有用的加密方式,因为公钥是可以公开的,而私钥是完全保密的,由此奠定了非对称加密的基础。

非对称加密确实是一种非常有用的加密方式,其基础就是公钥和私钥组成的密钥对。公钥可以公开,而私钥则是完全保密的,这种特性为非对称加密提供了很好的安全性。

在非对称加密中,加密和解密使用的不是相同的密钥。只有同一个密钥对中的公钥和私钥才能正常地进行加密和解密操作

因此,如果小明要向小红发送加密文件,他应该首先向小红索取她的公钥。然后,小明使用小红的公钥对文件进行加密,并将加密后的文件发送给小红。由于只有小红持有与公钥对应的私钥,因此只有小红能够使用她的私钥解密这个文件。其他人无法使用公钥解密文件,因为只有私钥的持有者才能解密数据。

这种方式确保了文件在传输过程中的安全性,只有具备私钥的接收方才能解密文件,保护了通信的机密性。


主流的非对称加密算法

主流的非对称加密算法包括:

  1. RSA(Rivest-Shamir-Adleman): RSA是最常用的非对称加密算法之一,它基于大数分解的数学难题。RSA算法可以用于加密、数字签名和密钥交换等场景,广泛应用于网络通信、数据传输和身份认证等领域。

  2. DSA(Digital Signature Algorithm): DSA是一种数字签名算法,专门用于生成和验证数字签名,常用于身份认证、数据完整性验证等场景。DSA算法基于离散对数的数学难题,相对于RSA算法,它的加密和解密速度更快。

  3. ECC(Elliptic Curve Cryptography): ECC是一种基于椭圆曲线的非对称加密算法,具有与RSA相当的安全性,但在密钥长度较短的情况下提供了更高的安全性,因此在资源受限的环境下更加适用。

  4. ElGamal: ElGamal是一种基于离散对数的非对称加密算法,主要用于密钥交换和加密通信。与RSA类似,ElGamal算法也可以用于加密和数字签名,但相对于RSA,ElGamal算法在实现和使用上更为复杂。

这些非对称加密算法在不同的场景下有着各自的优缺点和适用性,选择合适的算法取决于具体的安全需求、性能要求和应用环境。

在这里插入图片描述


典型算法:RSA

非对称加密的典型算法就是RSA算法,它是由Ron Rivest、Adi Shamir和Leonard Adleman这三位密码学家共同发明的,因此用他们三人的姓的首字母缩写表示。

相比对称加密,非对称加密有显著的优点。对称加密需要在通信双方之间协商共享密钥,而非对称加密则可以安全地公开各自的公钥。

  • 在N个人之间进行通信时,使用非对称加密只需要N个密钥对,每个人只需管理自己的密钥对。
  • 而使用对称加密时,则需要N*(N-1)/2个密钥,因此每个人需要管理N-1个密钥,密钥管理的难度大,并且容易导致密钥泄漏。

非对称加密的缺点就是运算速度非常慢,比对称加密要慢很多。 在实际应用中,通常会将非对称加密和对称加密结合使用,以充分发挥它们各自的优点,并弥补彼此的缺点。

假设小明需要向小红传输加密文件,他们可以采取以下步骤:

  1. 小明和小红首先交换各自的公钥,这可以在安全的通信渠道上完成。

  2. 小明生成一个随机的对称密钥(比如AES口令),然后使用小红的公钥通过RSA算法对这个对称密钥进行加密,得到密文。

  3. 小明将加密后的对称密钥发送给小红。

  4. 小红使用自己的RSA私钥对收到的密文进行解密,得到原始的对称密钥。

  5. 现在,小明和小红都拥有相同的对称密钥,他们可以使用对称加密算法(如AES)来加密和解密通信内容。由于对称加密算法的运算速度快,因此通信双方可以更高效地进行加密通信。

通过这种方式,非对称加密用于安全地传输对称密钥,而对称加密用于加密和解密实际的通信内容,既保证了安全性,又提高了效率。


Code

package com.artisan.securityalgjava.rsa;

import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;
/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class RSAExample {

    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();

        // 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 要加密的原始数据
        String plaintext = "Hello, RSA!";
        System.out.println("Plaintext: " + plaintext);

        // 使用公钥加密数据
        byte[] encryptedBytes = encryptRSA(plaintext.getBytes(), publicKey);
        String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("Encrypted text: " + encryptedText);

        // 使用私钥解密数据
        byte[] decryptedBytes = decryptRSA(Base64.getDecoder().decode(encryptedText), privateKey);
        String decryptedText = new String(decryptedBytes);
        System.out.println("Decrypted text: " + decryptedText);
    }

    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 设置密钥长度为2048位
        return keyPairGenerator.generateKeyPair();
    }

    // 使用公钥加密数据
    public static byte[] encryptRSA(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    // 使用私钥解密数据
    public static byte[] decryptRSA(byte[] encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encryptedData);
    }
}

输出:

Plaintext: Hello, RSA!
Encrypted text: CU+9ZlNmH3NR5SZSdpZRQmTyXQLU0SLX1d1ICoi/LjAu6a4lMsVXUfB+STFHglKOTVCEjddCJwoWVGXJDcm/nTqRVtB/qIV3+kt7W4/H2fvLeYf+mgbIyNNMyZU4h7k0rbVSTIdHpmfcV1ToYPNVtYarHQ0EbmD261iKeGBGb9HrprknspsXxfIMAEeKOEFotE/4fkwySCsWatANwOwjivEqZcDBnX/1BlhA9CIP4zd4osUoiRt/wJtBsx58/A+47Lf2wBo7C8YcRRpa2A8HxtxnOkhy0cciVeaAzMtaaiVDWbaBqML3sXu3iP3CDkrZQ2+VmBCTZX35y1fxCZ1/Dg==
Decrypted text: Hello, RSA!


package com.artisan.securityalgjava.rsa;

import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.*;

/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
public class RsaDemo {

    public static void main(String[] args) throws Exception {
        // 明文:
        byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");
        // 创建公钥/私钥对
        Person alice = new Person("Alice");
        // 用Alice的公钥加密:
        byte[] pk = alice.getPublicKey();
        System.out.println(String.format("public key: %x", new BigInteger(1, pk)));
        byte[] encrypted = alice.encrypt(plain);
        System.out.println(String.format("encrypted: %x", new BigInteger(1, encrypted)));

        // 用Alice的私钥解密:
        byte[] sk = alice.getPrivateKey();
        System.out.println(String.format("private key: %x", new BigInteger(1, sk)));
        byte[] decrypted = alice.decrypt(encrypted);
        System.out.println(new String(decrypted, "UTF-8"));
    }
}

class Person {
    String name;
    // 私钥:
    PrivateKey sk;
    // 公钥:
    PublicKey pk;

    public Person(String name) throws GeneralSecurityException {
        this.name = name;
        // 生成公钥/私钥对:
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
        kpGen.initialize(1024);
        KeyPair kp = kpGen.generateKeyPair();
        this.sk = kp.getPrivate();
        this.pk = kp.getPublic();
    }

    /**
     * 把私钥导出为字节
     * @return
     */
    public byte[] getPrivateKey() {
        return this.sk.getEncoded();
    }

    /**
     *  把公钥导出为字节
     * @return
     */
    public byte[] getPublicKey() {
        return this.pk.getEncoded();
    }

    /**
     * 用公钥加密
     * @param message
     * @return
     * @throws GeneralSecurityException
     */
    public byte[] encrypt(byte[] message) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, this.pk);
        return cipher.doFinal(message);
    }

    /**
     * 用私钥解密
     * @param input
     * @return
     * @throws GeneralSecurityException
     */
    public byte[] decrypt(byte[] input) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, this.sk);
        return cipher.doFinal(input);
    }
}
    

输出:

public key: 30819f300d06092a864886f70d010101050003818d00308189028181008c97547fab56c9af0f54d814581a7d695e0722c7029751e4d05530d28923c45ac29420e8cec253a71043e98dae2139cee1d97e125f73c0b32a91196a7154c3199cf6529942627e50796463fc7ab6c747ab0788fe67d3855c9f9348233277ef68d663c2df1232c5adb6d7d9be0aefe5e6c0bcdda48abf9570d732878b93c5bc6d0203010001
encrypted: 24bac571932a8f2c633660493a57e895e404c03824ba8fff87bfaaa655914eaeabd032beed102d24479c21e1c17ccfea5018708da42e28ec7e2f472b36f769f0aa0639bdff985babdbce3a9d357a89dcf31df2b00366f16708245c2a75a3c5d25aedd25207f3204416a6e431f305bd49b90eb0d40d6caed2bb4f068c183fb442
private key: 30820275020100300d06092a864886f70d01010105000482025f3082025b020100028181008c97547fab56c9af0f54d814581a7d695e0722c7029751e4d05530d28923c45ac29420e8cec253a71043e98dae2139cee1d97e125f73c0b32a91196a7154c3199cf6529942627e50796463fc7ab6c747ab0788fe67d3855c9f9348233277ef68d663c2df1232c5adb6d7d9be0aefe5e6c0bcdda48abf9570d732878b93c5bc6d02030100010281806b2753f1d2875d449decce9c02e27dbf7738fd1aad30e3ebff954e96c88b88369ca305ca2afc1581f975a966a0d716164630dc53e88872d09b9ae7c2270ab17f80e36bc78532d68216ecb3a62bc4ab84be8b6db08c48568622f2216e29609f3ae6db825c13d503554a923fe62850cd6fcf2221315c98946c3fd47c79f6bc5089024100fcc240d520a5106544a5cc764c9149c35fca005b9af0fcb5999fa5e4b69a1a5ca19f732e5a2633c0ceeceb7cc433e39f5fca0c7c9a1679ff9990029170adfe070241008e64db6f5b7270a69d4082c88db9c8c9909519b535bd8bf898f2fc6f3d7ac00c1fa8d2fa4614cb851f64f7bea021d60e5d27fe5f5aa0c21e0f05ef5f54e314eb0240460aca8e850258ddc73d2ec0a58d2964b3b9b589ad1114e67a10cc96e9a720a104c4bbd55f73f0a9806e14ffb91b2bfbb13ebb61180e1c76a126501fdf9ac7a7024020845bb0045c0fe99c837cda3bb32f6d083d644f836433b0a38ce9a4a58f8087c43b1362dfda23d7d4a18409de1b9bfc4fbdb0532a2907eb415703a0eb8ba7dd02401fee6a8ef7af9c5c723215500003984e5ded1bd31061ce5396bf5b55ab7cdbe8b6024863fd466eb8de13318863f485af479cc66b8d8a858f02b9b3254b0c1562
Hello, encrypt use RSA

RSA的公钥和私钥的恢复

RSA的公钥和私钥都可以通过getEncoded()方法获得以byte[]表示的二进制数据,并根据需要保存到文件中。

伪代码如下:

byte[] pkData = ...
byte[] skData = ...
KeyFactory kf = KeyFactory.getInstance("RSA");
// 恢复公钥:
X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pkData);
PublicKey pk = kf.generatePublic(pkSpec);
// 恢复私钥:
PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(skData);
PrivateKey sk = kf.generatePrivate(skSpec);

完整代码:

package com.artisan.securityalgjava.rsa;

import java.security.*;
import java.security.spec.*;
import java.util.Base64;

/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */

public class RSAKeyConversionExample {

    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();

        // 获取公钥和私钥
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 将公钥和私钥转换为byte[]数组
        byte[] publicKeyBytes = publicKey.getEncoded();
        byte[] privateKeyBytes = privateKey.getEncoded();

        // 将byte[]数组转换为Base64编码的字符串方便保存和传输
        String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
        String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKeyBytes);

        System.out.println("Public key (Base64): " + publicKeyBase64);
        System.out.println("Private key (Base64): " + privateKeyBase64);

        // 从Base64编码的字符串恢复公钥和私钥
        PublicKey restoredPublicKey = restorePublicKey(Base64.getDecoder().decode(publicKeyBase64));
        PrivateKey restoredPrivateKey = restorePrivateKey(Base64.getDecoder().decode(privateKeyBase64));

        // 验证恢复的公钥和私钥与原始的是否一致
        System.out.println("Restored public key equals original: " + publicKey.equals(restoredPublicKey));
        System.out.println("Restored private key equals original: " + privateKey.equals(restoredPrivateKey));
    }

    // 生成RSA密钥对
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 设置密钥长度为2048位
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 从byte[]数组恢复公钥
     * @param publicKeyBytes
     * @return
     * @throws Exception
     */
    public static PublicKey restorePublicKey(byte[] publicKeyBytes) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        return keyFactory.generatePublic(publicKeySpec);
    }

    /**
     * 从byte[]数组恢复私钥
     * @param privateKeyBytes
     * @return
     * @throws Exception
     */
    public static PrivateKey restorePrivateKey(byte[] privateKeyBytes) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        return keyFactory.generatePrivate(privateKeySpec);
    }
}

输出

Public key (Base64): MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApd4mRIUmxWx9+Jrp/Gp06gqRbgsGdy36Dshvrkz5ofiKe6guRfP/swimmsdZItPpfWJNn2BKQzTL32gSiZ5y+uU7EpkEDmg2Z6ip5jb0Dpt0/cTldD7ykG6AMlnpJwoFQXgNTCpgqOOhFRNRPTBLUjeVMeNeJPoVQKipdFTVrUU5NCZSHgvBWjngELmLZDdj1sJ/vCyEol1eg9N1G8c9kcyhbAhSGX7BSq3q/heuOPGjzHVTMJb2mKvGPst7fYdmUyVvW+ovF7AMf8AfemLrdZJ+mxi4dj2X5c2fKcNK32+zfJNhpQMdaLZtbHAAyvSVc6xGxiYYGAuUrFnGiY26XwIDAQAB
Private key (Base64): MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCl3iZEhSbFbH34mun8anTqCpFuCwZ3LfoOyG+uTPmh+Ip7qC5F8/+zCKaax1ki0+l9Yk2fYEpDNMvfaBKJnnL65TsSmQQOaDZnqKnmNvQOm3T9xOV0PvKQboAyWeknCgVBeA1MKmCo46EVE1E9MEtSN5Ux414k+hVAqKl0VNWtRTk0JlIeC8FaOeAQuYtkN2PWwn+8LISiXV6D03Ubxz2RzKFsCFIZfsFKrer+F6448aPMdVMwlvaYq8Y+y3t9h2ZTJW9b6i8XsAx/wB96Yut1kn6bGLh2PZflzZ8pw0rfb7N8k2GlAx1otm1scADK9JVzrEbGJhgYC5SsWcaJjbpfAgMBAAECggEAMndY5Vgt57uOyGk58Bbj46G7hePM384ZWw4ZDMtW2LUqTV1qVtZaYjqrlkQ5FqOrUv7p5ygA8FnL/flISp7vFO9R/eKYnVmP1BI5P1ZRA3DBM8UIm0nbu54jWy6IBdzCpJzGTvpF1p0LkcIC4b8j66wFtNwc9NsyRC4NANwe90ytm6/HrsoUlRgMeJv9QejfA8A3+VrF1Y1ozn7aSuElX6q7tdZ0kNEGN7qVdl1qilmcMiPpMLC5k7J7WpTeVZGeQM3Akm2LnbcAS5QMkSyhSZWj0n3e+kGRdmCBdRRCGQVsk2qeTahYZvtv1hJRe0mUbDEC/DWSDFLJudbSa5GAAQKBgQDxMFGpiQZ5IWrxh4Rh2CPJpZB1UfQjC5NI0kcKx8jXGp/GXoGfpcjmmF7yRg9ASeG1oOioZKdktSo7KRsSLKetG+L3W+pHkPaPMz/Vt788XuWAZKlBUJ0+02czeRjXDXY0B6Ik4uJ9okRuKO4EndWVhT/bSC2f6khergOe6HPqXwKBgQCwDbllyfGsRS0yn31KcNTjG2E9FMh9uhRP+0wcJR1dDqsXimQ1KE1cdWRsGWolA5oXaR8jNtSUc3NhuyYnjSoI/S2Z8VYnKdfDNb8x6pPV1RxCW5gRT2vrRxBnnN9bkI5ABhRKQslmAq+I0mYAueUGU+6c7iwNIfC8U+Kn+9gwAQKBgQCCQqloGdRAKXc7uQgbXAOADYYmhruHDeJe6wppXRswaXWvSi1RztThDZwB1yq3eu+HC7976tipQFrtlrbDKxDoIm6DT8YJHta64l/wigujjFEA9dyfpO04GC7dkuKCiwey9AhzSYIvfirdIAfkwGWxGkUxphrWCk9Jq0vTUBICmwKBgB62djZssW11L/pZ2ninEGyCNUd7nbJZSPvfAhsS2nmGepCDwxGG82AC1r8I+/xzEWmuHBF/mjw/m8xb4r8ZoFCrIk5tzLLOWOakNLOXkazHHcPxyKiUa2ZDIniA5HJL2JUQum9uEUZrh4Xd9o9/3pVpBQJ5hlPQLPgdxje59rABAoGAbXZS1iNDOJCw+FG2YsCxUWl0fqwW41ldT6qplckCZ/oZuMNXdxCI3ZNhS1juo0A9dL4tu1wJqHdenlYlmxcVpXfz65n2mdXIULnW4eQts5qKyxY/DImJbrxi0qrRGLd0C/GMxpChjoWLrT4in87JI9PiuJT8OpNq/kgs/z3V4VQ=
Restored public key equals original: true
Restored private key equals original: true

以RSA算法为例,它的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢

如果修改待加密的byte[]数据的大小,可以发现,使用512bit的RSA加密时,明文长度不能超过53字节,使用1024bit的RSA加密时,明文长度不能超过117字节,这也是为什么使用RSA的时候,总是配合AES一起使用,即用AES加密任意长度的明文,用RSA加密AES口令。

RSA算法的加密和解密操作中,密钥长度会影响可以处理的数据大小。一般来说,RSA加密操作能处理的最大数据块大小取决于密钥长度和填充模式。

在常见的填充模式下(如PKCS#1 v1.5或OAEP填充),RSA加密时需要对明文进行填充以满足算法要求的固定长度。这意味着,即使密钥长度较长,但实际能够加密的明文长度仍然受到限制

对于RSA加密,加密前需要对数据进行填充,以保证数据块的大小不超过密钥长度。填充的过程会增加一定的开销。一般来说,填充过程会使得实际能够加密的明文长度比密钥长度小一些。

具体来说,对于一个RSA密钥,它能够加密的最大数据块大小等于密钥长度减去一些填充的开销。因此,较短的密钥长度会限制加密的数据块大小。

在实际应用中,RSA算法的密钥长度一般选择较大的值(如2048位或更高),以提高安全性。但是,由于RSA算法加密的性能相对较慢,特别是在处理较大数据块时,因此通常不适合直接用于加密大量数据。相反,RSA常常与对称加密算法(如AES)结合使用,以提高性能和安全性。

因此,通常的做法是,使用RSA加密对称密钥(如AES密钥),然后使用对称密钥加密要传输的数据。这样既能保证安全性,又能提高加密和解密的性能。


小结

除了无法防止中间人攻击外,非对称加密算法还有一些其他缺点:

  1. 性能低下: 非对称加密算法的计算复杂度比对称加密算法高很多,特别是在处理大量数据时,性能会受到明显影响。因此,非对称加密算法通常用于密钥交换和数字签名等场景,而不适合直接加密大量数据。

  2. 密钥长度限制: 非对称加密算法的密钥长度会直接影响其安全性,通常需要选择较长的密钥长度以确保安全性。然而,较长的密钥长度会导致加密和解密的速度变慢,从而增加了计算的开销。

  3. 密钥管理复杂: 非对称加密算法需要管理公钥和私钥,密钥的生成、存储、分发和更新都需要一定的机制和流程来保证安全性。特别是在大规模系统中,密钥管理可能会变得非常复杂和困难。

  4. 安全性依赖于实现和使用: 非对称加密算法的安全性取决于其算法的设计和实现,以及密钥的生成和使用方式。如果实现存在漏洞或者密钥管理不当,可能会导致加密系统的安全性受到威胁。

综上所述,虽然非对称加密算法在密钥交换和数字签名等方面具有重要的作用,但其性能和安全性方面存在一些局限性,因此在实际应用中需要根据具体情况综合考虑,选择合适的加密方案。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】npm run build 打包报错:请在[.env.local]中填入key后方可使用...

报错如下 根目录添加 .env.local 文件 .env.local :本地运行下的配置文件 配置:VUE_GITHUB_USER_NAME 及 VUE_APP_SECRET_KEY 原因

通过GitHub探索Python爬虫技术

1.检索爬取内容案例。 2.找到最近更新的。(最新一般都可以直接运行) 3.选择适合自己的项目,目前测试下面画红圈的是可行的。 4.方便大家查看就把代码粘贴出来了。 #图中画圈一代码 import requests import os import rewhile True:music_id input("请输入歌曲…

文本多分类

还在用BERT做文本分类?分享一套基于预训练模型ERNIR3.0的文本多分类全流程实例【文本分类】_ernir 文本分类-CSDN博客 /usr/bin/python3 -m pip install --upgrade pip python3-c"import platform;print(platform.architecture()[0]);print(platform.machine…

Mysql主从备份

主从复制概述 将主服务器的binlog日志复制到从服务器上执行一遍,达到主从数据的一致状态,称之为主从复制。一句话表示就是,主数据库做什么,从数据库就跟着做什么。 为什么要使用主从复制 为实现服务器负载均衡/读写分离做铺垫&…

Chrome插件 | WEB 网页数据采集和爬虫程序

无边无形的互联网遍地是数据,品类丰富、格式繁多,包罗万象。数据采集,或说抓取,就是把分散各处的内容,通过各种方式汇聚一堂,是个有讲究要思考的体力活。君子爱数,取之有道,得注意遵…

Tomcat 架构

一、Http工作原理 HTTP协议是浏览器与服务器之间的数据传送协议。作为应用层协议,HTTP是基于TCP/IP协议来传递数据的(HTML文件、图片、查询结果等),HTTP协议不涉及数据包(Packet)传输,主要规定了…

Ai-WB2-32S在window下使用vs 和 msys2编译以及烧录

文章目录 前言一、使用前准备第一步 安装vscode第二步 安装msys2 二、使用步骤1.打开MSYS2 MINGW64(1)在开始栏中找到MSYS2 MINGW64并打开(2)安装git(3)安装make(4)安装好之后的文件…

端游如何防破解

在2023年这个游戏大年中,诸多热门大作涌现,作为世界级IP哈利哈利波特的衍生游戏——《霍格沃茨之遗》毫无悬念地成为2023年游戏圈的首款爆款作品,斩获了一众玩家的青睐。 在众多光环的加持下,《霍格沃茨之遗》很快被著名游戏破解…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《激发多元灵活性的数据中心协同优化运行方法》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 这篇文章标题表明,其主题…

网络防御第6次作业

防病毒网关 按照传播方式分类 病毒 病毒是一种基于硬件和操作系统的程序,具有感染和破坏能力,这与病毒程序的结构有关。病毒攻击的宿主程序是病毒的栖身地,它是病毒传播的目的地,又是下一次感染的出发点。计算机病毒感染的一般过…

持安科技亮相张江高科895创业营,总评分第三名荣获「最具创新性企业」!

近日,张江高科895创业营(第十三季)信息安全专场Demo day&结营仪式在上海集成电路设计产业园圆满落幕。本季创业营通过多种渠道在海内外甄选优秀创业项目,一共择优录取了29家入营,最终甄选出9家代表参加Demo day路演…

安装ProxySQL,教程及安装链接(网盘自提)

一、网盘下载,本地直传 我网盘分享的是proxysql-2.5.5-1-centos8.x86_64.rpm,yum或者dnf直接安装就行 提取码:rhelhttps://pan.baidu.com/s/1nmx8-h8JEhrxQE3jsB7YQw 官方安装地址 官网下载地址https://repo.proxysql.com/ProxySQL/ 二、…

c# cad2016系统变量解释说明

一、cad系统变量设置和获取 /// <summary> /// 设置CAD系统变量 /// </summary> /// <param name"name">变量名</param> /// <param name"value">变量值</param> public static void SetSystemVariable(string name,…

[pdf]《软件方法》2024版部分公开-共196页

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 潘加宇《软件方法》2024版部分公开pdf文件&#xff0c;共196页&#xff0c;已上传CSDN资源。 也可到以下地址下载&#xff1a; http://www.umlchina.com/url/softmeth2024.html 如果…

DDOS攻击处理方法

DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一种网络攻击&#xff0c;攻击者通过发送大量的请求&#xff0c;超过目标服务器的处理能力&#xff0c;导致服务器服务不可用。本文将介绍如何处理DDoS攻击&#xff0c;并提供几种防范措施。 1. 认识DDoS攻击 DDoS攻击通常通过…

JAVA对象内存模型

Java对象内存模型 > 一个Java对象在内存中包括3个部分&#xff1a;对象头、实例数据和对齐填充 > > 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压…

mac 本地使用dockerfile启动 springboot项目

1.创建Dockerfile放在项目的根目录下 2.编写Dockerfile FROM openjdk:11 MAINTAINER ChengLinADD target/JiaLi-0.0.1-SNAPSHOT.jar /app.jar# 暴露 Spring Boot 应用的端口号 EXPOSE 8088 # 启动 Spring Boot 应用 CMD ["java", "-jar", "app.jar&q…

机器学习 | 模型性能评估

目录 一. 回归模型的性能评估1. 平均平方误差(MSE)2. 平均绝对误差(MAE)3. R 2 R^{2} R2 值3.1 R 2 R^{2} R2优点 二. 分类模型的性能评估1. 准确率&#xff08;Accuracy&#xff09;2. 召回率&#xff08;Recall&#xff09;3. 精确率&#xff08;Precision&#xff09;4. …

【测试开发面试复习(一)】计算机网络:应用层详解(P2)补充ing

复习自用&#xff0c;若有错漏&#xff0c;欢迎一起交流一下~~ 一、高频面试题记录 uri 和 url 的区别 &#xff1f; dns 是啥工作原理&#xff0c;主要解析过程是啥&#xff1f; 用户输入网址到显示对应页面的全过程是啥&#xff1f; http 头部包含哪些信息&#xff1f; http…

水电站泄洪预警系统解决方案

水电站建立的初衷有两个&#xff0c;一是用于发电&#xff0c;二是用于调节水量&#xff0c;解决下游洪涝灾害。水电站在丰水期蓄水、枯水期泄洪&#xff0c;泄洪时产生的水流又急又大&#xff0c;对电站大坝及下游存在巨大危险。为了加强水电站工程安全管理&#xff0c;保证水…