DES算法(Python实现)

news2024/11/24 20:24:07
  • 一、具体描述

基于计算机高级语言(如C语言)实现DES算法

  • 二、名词术语与相关知识

DES算法

DES(Data Encryption Standard)是一种对称加密算法,被广泛应用于数据加密领域。它使用64位密钥和64位明文,通过一系列的操作将明文加密成密文。

初始置换和逆初始置换

初始置换IP和逆初始置换IP^-1是DES算法中的两个置换操作。初始置换将64位明文按照特定的顺序重新排列,得到一个新的64位数据块;逆初始置换是初始置换的逆操作,将密文还原为明文。

扩展运算

扩展运算是DES算法中的一个操作,用于将32位数据扩展为48位。该操作使用选择置换矩阵E对32位数据进行扩展,并生成一个48位的数据块。

S盒变换

S盒变换是DES算法中的一个操作,用于将48位数据压缩为32位。该操作使用8个不同的S盒,在输入48位数据时输出32位数据。每个S盒都是一个4x16的置换表,用于将6位输入映射到4位输出。

置换运算

置换运算是DES算法中的一个操作,用于将32位数据根据特定的置换表进行置换。DES算法中使用的置换表有选择置换矩阵P和置换选择矩阵PC-1、PC-2。

子密钥生成

子密钥生成是DES算法中的一个步骤,用于生成16个48位的子密钥。该过程使用置换选择矩阵PC-1和PC-2,以及循环左移和压缩操作,从64位密钥中生成16个48位子密钥。

异或运算

异或运算是一种逻辑运算,用于对两个二进制数进行比较。当两个数的位相同时,结果为0,不同时,结果为1。

三、DES算法原理和实现方法

  1. 算法简介:DES算法是对称加密算法,也就是加密和解密的密钥相同。

DES算法的主要内容:DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或者解密。

  1. 算法实现:

1.算法流程:

百度DES算法图

  1. 算法实现:

对算法流程图进行总结得出,DES算法的基本框架为:

(1)对明文二进制进行IP置换

(2)对IP置换后的数据进行分割为L0和R0(即左32位和右32位)

(3)根据密钥进行对每一轮的子密钥计算(16轮相同运算)

(4)获取到下一轮的Ln和Rn,中间的Kn和计算函数f

(5)合并最后得到的L15和R15进行IP逆置换得到加密后的密文

    1. IP置换和IP逆置换
  1. IP置换是将64位数据重新换位,分为左32位和右32位,如下是IP置换表

58

50

42

34

26

18

10

2

60

52

44

36

28

20

12

4

62

54

46

38

30

22

14

6

64

56

48

40

32

24

16

8

57

49

41

33

25

17

9

1

59

51

43

35

27

19

11

3

61

53

45

37

29

21

13

5

63

55

47

39

31

23

15

7

  1. IP逆置换和IP置换是一样的操作,IP逆置换表如下

40

8

48

16

56

24

64

32

39

7

47

15

55

23

63

31

38

6

46

14

54

22

62

30

37

5

45

13

53

21

61

29

36

4

44

12

52

20

60

28

35

3

43

11

51

19

59

27

34

2

42

10

50

18

58

26

33

1

41

9

49

17

57

25

    1. 计算每轮子密钥

DES密钥从64位变为56位,56位密钥由密钥置换表得到

57

49

41

33

25

17

9

1

58

50

42

34

26

18

10

2

59

51

43

35

27

19

11

3

60

52

44

36

63

55

47

39

31

23

15

7

62

54

46

38

30

22

14

6

61

53

45

37

29

21

13

5

28

20

12

4

DES的每轮子密钥,是从56位的密钥中产生处不同的子密钥,确定子密钥方式如下:

  1. 将56位的密钥分为两部分,28位为一部分
  2. 根据不同的轮数,每部分循环左移1位或者2位置,移动的位数表如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

1

1

2

2

2

2

2

2

1

2

2

2

2

2

2

1

移动之后,从56位中选48位,在密钥压缩置换后确定子密钥,压缩表如下

14

17

11

24

1

5

3

28

15

6

21

10

23

19

12

4

26

8

16

7

27

20

13

2

41

52

31

37

47

55

30

40

51

45

33

48

44

49

39

56

34

53

46

42

50

36

29

32

    1. f函数和异或运算

这里主要包括E拓展置换、S盒代替、P盒置换,就不再具体阐述了。

3.Python实现

  • 初始化

self.ipIP置换self.ip1逆IP置换self.EE置换,32位明文置换为48位self.PP置换,对S盒后的数据再次置换self.K默认密钥0101010001101000011010010101001101101001011101110110100101110110

self.k1密钥K1初始置换self.k0密钥循环移位位数self.SS盒数据,8个S盒

二、def的函数和接口

(1)def __substitution(self, table: str, self_table: list) -> str:置换函数:密钥、IP等

2)def str2bin(self, string: str) -> str:明文转换为二进制字符串

3)def bin2str(self, binary: str) -> str:二进制字符串转成字符串

4)def __bin2int(self, binary: str) -> list:将二进制字符串每8位转成int列表

5)def __int2bin(self, list_int: list) -> str:将int类型的列表转成二进制串

6)def __get_block_list(self, binary: str) -> list:对二进制串进行切分,每64位为一块

7)def modify_secretkey(self):修改默认密钥函数

8)ef __f_funtion(self, right: str, key: str):对right进行E拓展,与key进行异或操作,进入S盒子,进行P置换

9)def __get_key_list(self):返回加密过程中16轮的子密钥

10)def __xor_function(self, xor1: str, xor2: str):异或操作返回的结果

11)def __s_box(self, xor_result: str):S盒置换返回32位

 (12)def __iteration(self, bin_plaintext: str, key_list: list):(进行F函数以及左异或操作之后的字符串)

 (13)def encode(self, plaintext):(加密接口)

 (14)def decode(self, ciphertext):(解密)

三、实现过程截图

(1)开始运行后可以选择自己输入8位长度的密钥,然后可以进行加密和解密的选择

(2)选择加密,这里加密内容为:I love you!,可以得到加密后的密文为:

7B3BB376B983351445C6D1D9E6DA2847

(3)选择对刚刚加密的内容解密,就可以得到加密前的明文了。

四、Python代码

import binascii
class ArrangeSimpleDES():
    def __init__(self):
        # 出初始化DES加密的参数
        self.ip = [
            58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
            62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
            57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
            61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7,
        ]  # ip置换

        self.ip1 = [
            40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
            38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
            36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
            34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25,
        ]  # 逆ip置换
        self.E = [
            32, 1, 2, 3, 4, 5,
            4, 5, 6, 7, 8, 9,
            8, 9, 10, 11, 12, 13,
            12, 13, 14, 15, 16, 17,
            16, 17, 18, 19, 20, 21,
            20, 21, 22, 23, 24, 25,
            24, 25, 26, 27, 28, 29,
            28, 29, 30, 31, 32, 1,
        ]  # E置换,将32位明文置换位48位
        self.P = [
            16, 7, 20, 21, 29, 12, 28, 17,
            1, 15, 23, 26, 5, 18, 31, 10,
            2, 8, 24, 14, 32, 27, 3, 9,
            19, 13, 30, 6, 22, 11, 4, 25,
        ]  # P置换,对经过S盒之后的数据再次进行置换
        # 设置默认密钥
        # self.K = '0111010001101000011010010111001101101001011100110110100101110110'
        self.K = '0101010001101000011010010101001101101001011101110110100101110110'
        self.k1 = [
            57, 49, 41, 33, 25, 17, 9,
            1, 58, 50, 42, 34, 26, 18,
            10, 2, 59, 51, 43, 35, 27,
            19, 11, 3, 60, 52, 44, 36,
            63, 55, 47, 39, 31, 23, 15,
            7, 62, 54, 46, 38, 30, 22,
            14, 6, 61, 53, 45, 37, 29,
            21, 13, 5, 28, 20, 12, 4,
        ]  # 密钥的K1初始置换
        self.k2 = [
            14, 17, 11, 24, 1, 5, 3, 28,
            15, 6, 21, 10, 23, 19, 12, 4,
            26, 8, 16, 7, 27, 20, 13, 2,
            41, 52, 31, 37, 47, 55, 30, 40,
            51, 45, 33, 48, 44, 49, 39, 56,
            34, 53, 46, 42, 50, 36, 29, 32,
        ]

        self.k0 = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, ]  # 秘钥循环移位的位数

        self.S = [
            [
                0xe, 0x4, 0xd, 0x1, 0x2, 0xf, 0xb, 0x8, 0x3, 0xa, 0x6, 0xc, 0x5, 0x9, 0x0, 0x7,
                0x0, 0xf, 0x7, 0x4, 0xe, 0x2, 0xd, 0x1, 0xa, 0x6, 0xc, 0xb, 0x9, 0x5, 0x3, 0x8,
                0x4, 0x1, 0xe, 0x8, 0xd, 0x6, 0x2, 0xb, 0xf, 0xc, 0x9, 0x7, 0x3, 0xa, 0x5, 0x0,
                0xf, 0xc, 0x8, 0x2, 0x4, 0x9, 0x1, 0x7, 0x5, 0xb, 0x3, 0xe, 0xa, 0x0, 0x6, 0xd,
            ],
            [
                0xf, 0x1, 0x8, 0xe, 0x6, 0xb, 0x3, 0x4, 0x9, 0x7, 0x2, 0xd, 0xc, 0x0, 0x5, 0xa,
                0x3, 0xd, 0x4, 0x7, 0xf, 0x2, 0x8, 0xe, 0xc, 0x0, 0x1, 0xa, 0x6, 0x9, 0xb, 0x5,
                0x0, 0xe, 0x7, 0xb, 0xa, 0x4, 0xd, 0x1, 0x5, 0x8, 0xc, 0x6, 0x9, 0x3, 0x2, 0xf,
                0xd, 0x8, 0xa, 0x1, 0x3, 0xf, 0x4, 0x2, 0xb, 0x6, 0x7, 0xc, 0x0, 0x5, 0xe, 0x9,
            ],
            [
                0xa, 0x0, 0x9, 0xe, 0x6, 0x3, 0xf, 0x5, 0x1, 0xd, 0xc, 0x7, 0xb, 0x4, 0x2, 0x8,
                0xd, 0x7, 0x0, 0x9, 0x3, 0x4, 0x6, 0xa, 0x2, 0x8, 0x5, 0xe, 0xc, 0xb, 0xf, 0x1,
                0xd, 0x6, 0x4, 0x9, 0x8, 0xf, 0x3, 0x0, 0xb, 0x1, 0x2, 0xc, 0x5, 0xa, 0xe, 0x7,
                0x1, 0xa, 0xd, 0x0, 0x6, 0x9, 0x8, 0x7, 0x4, 0xf, 0xe, 0x3, 0xb, 0x5, 0x2, 0xc,
            ],
            [
                0x7, 0xd, 0xe, 0x3, 0x0, 0x6, 0x9, 0xa, 0x1, 0x2, 0x8, 0x5, 0xb, 0xc, 0x4, 0xf,
                0xd, 0x8, 0xb, 0x5, 0x6, 0xf, 0x0, 0x3, 0x4, 0x7, 0x2, 0xc, 0x1, 0xa, 0xe, 0x9,
                0xa, 0x6, 0x9, 0x0, 0xc, 0xb, 0x7, 0xd, 0xf, 0x1, 0x3, 0xe, 0x5, 0x2, 0x8, 0x4,
                0x3, 0xf, 0x0, 0x6, 0xa, 0x1, 0xd, 0x8, 0x9, 0x4, 0x5, 0xb, 0xc, 0x7, 0x2, 0xe,
            ],
            [
                0x2, 0xc, 0x4, 0x1, 0x7, 0xa, 0xb, 0x6, 0x8, 0x5, 0x3, 0xf, 0xd, 0x0, 0xe, 0x9,
                0xe, 0xb, 0x2, 0xc, 0x4, 0x7, 0xd, 0x1, 0x5, 0x0, 0xf, 0xa, 0x3, 0x9, 0x8, 0x6,
                0x4, 0x2, 0x1, 0xb, 0xa, 0xd, 0x7, 0x8, 0xf, 0x9, 0xc, 0x5, 0x6, 0x3, 0x0, 0xe,
                0xb, 0x8, 0xc, 0x7, 0x1, 0xe, 0x2, 0xd, 0x6, 0xf, 0x0, 0x9, 0xa, 0x4, 0x5, 0x3,
            ],
            [
                0xc, 0x1, 0xa, 0xf, 0x9, 0x2, 0x6, 0x8, 0x0, 0xd, 0x3, 0x4, 0xe, 0x7, 0x5, 0xb,
                0xa, 0xf, 0x4, 0x2, 0x7, 0xc, 0x9, 0x5, 0x6, 0x1, 0xd, 0xe, 0x0, 0xb, 0x3, 0x8,
                0x9, 0xe, 0xf, 0x5, 0x2, 0x8, 0xc, 0x3, 0x7, 0x0, 0x4, 0xa, 0x1, 0xd, 0xb, 0x6,
                0x4, 0x3, 0x2, 0xc, 0x9, 0x5, 0xf, 0xa, 0xb, 0xe, 0x1, 0x7, 0x6, 0x0, 0x8, 0xd,
            ],
            [
                0x4, 0xb, 0x2, 0xe, 0xf, 0x0, 0x8, 0xd, 0x3, 0xc, 0x9, 0x7, 0x5, 0xa, 0x6, 0x1,
                0xd, 0x0, 0xb, 0x7, 0x4, 0x9, 0x1, 0xa, 0xe, 0x3, 0x5, 0xc, 0x2, 0xf, 0x8, 0x6,
                0x1, 0x4, 0xb, 0xd, 0xc, 0x3, 0x7, 0xe, 0xa, 0xf, 0x6, 0x8, 0x0, 0x5, 0x9, 0x2,
                0x6, 0xb, 0xd, 0x8, 0x1, 0x4, 0xa, 0x7, 0x9, 0x5, 0x0, 0xf, 0xe, 0x2, 0x3, 0xc,
            ],
            [
                0xd, 0x2, 0x8, 0x4, 0x6, 0xf, 0xb, 0x1, 0xa, 0x9, 0x3, 0xe, 0x5, 0x0, 0xc, 0x7,
                0x1, 0xf, 0xd, 0x8, 0xa, 0x3, 0x7, 0x4, 0xc, 0x5, 0x6, 0xb, 0x0, 0xe, 0x9, 0x2,
                0x7, 0xb, 0x4, 0x1, 0x9, 0xc, 0xe, 0x2, 0x0, 0x6, 0xa, 0xd, 0xf, 0x3, 0x5, 0x8,
                0x2, 0x1, 0xe, 0x7, 0x4, 0xa, 0x8, 0xd, 0xf, 0xc, 0x9, 0x0, 0x3, 0x5, 0x6, 0xb,
            ],
        ]  # 16进制表示S盒的数据,S盒是为了将48位转换为32位,有8个盒子

    def __substitution(self, table: str, self_table: list) -> str:
        """
        :param table: 需要进行置换的列表,是一个01字符串
        :param self_table: 置换表,在__init__中初始化了
        :return: 返回置换后的01字符串
        """
        sub_result = ""
        for i in self_table:
            sub_result += table[i - 1]
        return sub_result

    def str2bin(self, string: str) -> str:
        """
        将明文转为二进制字符串:
        :param string: 任意字符串
        :return:二进制字符串
        """
        plaintext_list = list(bytes(string, 'utf8'))  # 将字符串转成bytes类型,再转成list
        result = []  # 定义返回结果
        for num in plaintext_list:
            result.append(bin(num)[2:].zfill(8))  # 将列表的每个元素转成二进制字符串,8位宽度
        return "".join(result)

    def bin2str(self, binary: str) -> str:
        """
        二进制字符串转成字符串
        :param binary:
        :return:
        """
        list_bin = [binary[i:i + 8] for i in range(0, len(binary), 8)]  # 对二进制字符串进行切分,每8位为一组
        list_int = []
        for b in list_bin:
            list_int.append(int(b, 2))  # 对二进制转成int
        result = bytes(list_int).decode()  # 将列表转成bytes,在进行解码,得到字符串
        return result

    def __bin2int(self, binary: str) -> list:
        """
        由于加密之后的二进制无法直接转成字符,有不可见字符在,utf8可能无法解码,所以需要将二进制字符串每8位转成int型号列表,用于转成bytes再转hex
        :param binary: 二进制字符串
        :return: int型列表
        """
        list_bin = [binary[i:i + 8] for i in range(0, len(binary), 8)]  # 对二进制字符串进行切分,每8位为一组
        list_int = []
        for b in list_bin:
            list_int.append(int(b, 2))
        return list_int

    def __int2bin(self, list_int: list) -> str:
        result = []
        for num in list_int:
            result.append(bin(num)[2:].zfill(8))
        return ''.join(result)

    def __get_block_list(self, binary: str) -> list:
        """
        对明文二进制串进行切分,每64位为一块,DES加密以64位为一组进行加密的
        :type binary: 二进制串
        """
        len_binary = len(binary)
        if len_binary % 64 != 0:
            binary_block = binary + ("0" * (64 - (len_binary % 64)))
            return [binary_block[i:i + 64] for i in range(0, len(binary_block), 64)]
        else:
            return [binary[j:j + 64] for j in range(0, len(binary), 64)]

    def modify_secretkey(self):
        """
        修改默认密钥函数
        :return: None
        """
        print('默认二进制形式密钥为:{}'.format(self.K))
        print("字符串形式密钥为:{}".format(self.bin2str(self.K)))
        newkey = input("输入新的密钥(长度为8):")
        if len(newkey) != 8:
            print("密钥长度不符合,请重新输入:")
            self.modify_secretkey()
        else:
            bin_key = self.str2bin(newkey)
            self.K = bin_key
            print("新的二进制形式密钥为:{}".format(self.K))

    def __f_funtion(self, right: str, key: str):
        """
        :param right: 明文二进制的字符串加密过程的右半段
        :param key: 当前轮数的密钥
        :return: 进行E扩展,与key异或操作,S盒操作后返回32位01字符串
        """
        # 对right进行E扩展
        e_result = self.__substitution(right, self.E)
        # 与key 进行异或操作
        xor_result = self.__xor_function(e_result, key)
        # 进入S盒子
        s_result = self.__s_box(xor_result)
        # 进行P置换
        p_result = self.__substitution(s_result, self.P)
        return p_result

    def __get_key_list(self):
        """
        :return: 返回加密过程中16轮的子密钥
        """
        key = self.__substitution(self.K, self.k1)
        left_key = key[0:28]
        right_key = key[28:56]
        keys = []
        for i in range(1, 17):
            move = self.k0[i - 1]
            move_left = left_key[move:28] + left_key[0:move]
            move_right = right_key[move:28] + right_key[0:move]
            left_key = move_left
            right_key = move_right
            move_key = left_key + right_key
            ki = self.__substitution(move_key, self.k2)
            keys.append(ki)
        return keys

    def __xor_function(self, xor1: str, xor2: str):
        """
        :param xor1: 01字符串
        :param xor2: 01字符串
        :return: 异或操作返回的结果
        """
        size = len(xor1)
        result = ""
        for i in range(0, size):
            result += '0' if xor1[i] == xor2[i] else '1'
        return result

    def __s_box(self, xor_result: str):
        """
        :param xor_result: 48位01字符串
        :return: 返回32位01字符串
        """
        result = ""
        for i in range(0, 8):
            # 将48位数据分为6组,循环进行
            block = xor_result[i * 6:(i + 1) * 6]
            line = int(block[0] + block[5], 2)
            colmn = int(block[1:4], 2)
            res = bin(self.S[i][line * 16 + colmn])[2:]
            if len(res) < 4:
                res = '0' * (4 - len(res)) + res
            result += res
        return result

    def __iteration(self, bin_plaintext: str, key_list: list):
        """
        :param bin_plaintext: 01字符串,64位
        :param key_list: 密钥列表,共16个
        :return: 进行F函数以及和left异或操作之后的字符串
        """
        left = bin_plaintext[0:32]
        right = bin_plaintext[32:64]
        for i in range(0, 16):
            next_lift = right
            f_result = self.__f_funtion(right, key_list[i])
            next_right = self.__xor_function(left, f_result)
            left = next_lift
            right = next_right
        bin_plaintext_result = left + right
        return bin_plaintext_result[32:] + bin_plaintext_result[:32]

    def encode(self, plaintext):
        """
        :param plaintext: 明文字符串
        :return: 密文字符串
        """
        bin_plaintext = self.str2bin(plaintext)
        bin_plaintext_block = self.__get_block_list(bin_plaintext)
        ciphertext_bin_list = []
        key_list = self.__get_key_list()
        for block in bin_plaintext_block:
            # 初代ip置换
            sub_ip = self.__substitution(block, self.ip)
            ite_result = self.__iteration(sub_ip, key_list)
            # 逆ip置换
            sub_ip1 = self.__substitution(ite_result, self.ip1)
            ciphertext_bin_list.append(sub_ip1)
        ciphertext_bin = ''.join(ciphertext_bin_list)
        result = self.__bin2int(ciphertext_bin)
        return bytes(result).hex().upper()

    def decode(self, ciphertext):
        '''
        :param ciphertext: 密文字符串
        :return: 明文字符串
        '''
        b_ciphertext = binascii.a2b_hex(ciphertext)
        bin_ciphertext = self.__int2bin(list(b_ciphertext))
        bin_plaintext_list = []
        key_list = self.__get_key_list()
        key_list = key_list[::-1]
        bin_ciphertext_block = [bin_ciphertext[i:i + 64] for i in range(0, len(bin_ciphertext), 64)]
        for block in bin_ciphertext_block:
            sub_ip = self.__substitution(block, self.ip)
            ite = self.__iteration(sub_ip, key_list)
            sub_ip1 = self.__substitution(ite, self.ip1)
            bin_plaintext_list.append(sub_ip1)
        bin_plaintext = ''.join(bin_plaintext_list).replace('00000000', '')
        return self.bin2str(bin_plaintext)

    def main(self):
        select = input("请选择方式:\n1、加密\t 2、解密\n选择:")
        if select == '1':
            plaintext = input("输入要加密的内容:")
            # print("Your plaintext is:{}".format(plaintext))
            ciphertext = self.encode(plaintext)
            print("加密后是:{}".format(ciphertext))
        elif select == '2':
            plaintext = input("输入要解密的内容:")
            # print("Your ciphertext is:{}".format(plaintext))
            plaintext = self.decode(plaintext)
            print("解密的内容是:{}".format(plaintext))
            # print(len(plaintext))
        else:
            input("Please selecting again!")
            self.main()


if __name__ == '__main__':
    mydes = ArrangeSimpleDES()
    mydes.modify_secretkey()
    while True:
        mydes.main()
        print("")

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

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

相关文章

西门子WinCC的C脚本——对象的事件任务

1、 全局脚本编辑器&#xff1b; 2、 对象的属性任务&#xff1b; 3、 对象的事件任务。 本文探讨一下用C脚本来实现对象的事件任务。 一、例程说明引文&#xff1a;博途工控人平时在哪里技术交流博途工控人社群 如图1所示&#xff0c;为本例程的运行画面。本例程实现以下…

大数据 Hive - 实现SQL执行

文章目录 MapReduce实现SQL的原理Hive的架构Hive如何实现join操作小结 MapReduce的出现大大简化了大数据编程的难度&#xff0c;使得大数据计算不再是高不可攀的技术圣殿&#xff0c;普通工程师也能使用MapReduce开发大数据程序。 但是对于经常需要进行大数据计算的人&#xff…

没经验没资金,适合穷人创业项目的低成本生意

什么人可以赚到钱呢&#xff1f;不管你怎么都赚不到&#xff0c;那归根结底是因为你身边没有明白人。像我们普通人一没经验二没资金三没人脉&#xff0c;该如何创业呢&#xff1f; 第一点&#xff0c;如果你不知道干什么&#xff0c;就做黄牛&#xff0c;只当渠道&#xff0c;只…

Web前端篇——ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部

ElementUI之el-scrollbar el-backtop el-timeline实现时间轴触底刷新和一键返回页面顶部。 背景&#xff1a;ElementUI的版本&#xff08;vue.global.js 3.2.36&#xff0c; index.css 2.4.4&#xff0c; index.full.js 2.4.4&#xff09; 废话不多说&#xff0c;先看动…

猫头虎分享已解决Bug || Error: ImagePullBackOff (K8s)

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

(二)Explain使用与详解

explain中的列 sql语句: EXPLAIN SELECT * from user WHERE userId=1340; 执行结果: 1. id列 id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。 id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行…

python股票分析挖掘预测技术指标知识之蜡烛图指标(6)

本人股市多年的老韭菜&#xff0c;各种股票分析书籍&#xff0c;技术指标书籍阅历无数&#xff0c;萌发想法&#xff0c;何不自己开发个股票预测分析软件&#xff0c;选择python因为够强大&#xff0c;它提供了很多高效便捷的数据分析工具包。 我们已经初步的接触与学习其中数…

7.27 SpringBoot项目实战 之 整合Swagger

文章目录 前言一、Maven依赖二、编写Swagger配置类三、编写接口配置3.1 控制器Controller 配置描述3.2 接口API 配置描述3.3 参数配置描述3.4 忽略API四、全局参数配置五、启用增强功能六、调试前言 在我们实现了那么多API以后,进入前后端联调阶段,需要给前端同学提供接口文…

软件测试|Python中的变量与关键字详解

简介 在Python编程中&#xff0c;变量和关键字是非常重要的概念。它们是构建和控制程序的基本要素。本文将深入介绍Python中的变量和关键字&#xff0c;包括它们的定义、使用方法以及一些常见注意事项。 变量 变量的定义 变量是用于存储数据值的名称。在Python中&#xff0…

java每日一题——输出9x9乘法表(答案及编程思路)

前言&#xff1a; 打好基础&#xff0c;daydayup! 题目&#xff1a;输出下图9x9乘法表 编程思路&#xff1a;java只能输出行&#xff0c;不能输出列&#xff0c;所以考虑好每一行输出的内容即可 public class demo {public static void main(String[] args) {for (int i 1; i…

静态网页设计——清雅古筝网(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1T64y1K7Zn/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…

物理机与vm文件共享与传输的设置方法

今天跟各位小伙伴&#xff0c;分享一下物理机与vm虚拟机文件共享与传输的设置方法&#xff0c;以供大家参考&#xff01; 一、物理机与虚拟机文件共享设置方法 第一步&#xff1a;先关闭虚拟机&#xff08;客户机&#xff09; 第二步&#xff1a;选择编辑虚拟机设置 第三步&am…

Java研学-Servlet3.0文件上传下载

一 文件上传 1 介绍 用户选择本地文件资源保存到服务器上&#xff0c;Servlet需要将二进制数据以文件保存到服务器磁盘中&#xff0c;再将磁盘路径保存到数据库中 2 项目搭建 创建web项目&#xff0c;并添加对应jar包(JSTL) 3 API HttpServletRequest 方法–从请求中解析上…

mysql使用load data导入数据

windows环境&#xff0c;使用bat脚本sql脚本 bat脚本 echo off ::调用数据入库sql脚本 set hour%time:~0,2% if "%time:~0,1%"" " set hour0%time:~1,1% set now%Date:~0,4%%Date:~5,2%%Date:~8,2%%hour%%Time:~3,2%%Time:~6,2% echo %now% ::数据库地址…

【Python机器学习】朴素贝叶斯分类器

朴素贝叶斯分类器是与线性模型非常相似的一种分类器&#xff0c;它的训练速度往往更快&#xff0c;但是泛化能力比线性分类器稍差。 朴素贝叶斯分类器高效的原因是&#xff1a;通过单独查看每个特征来学习参数&#xff0c;并从每个特征中收集简单的类别统计数据。 scikit-lea…

C盘突然满了,怎么清理

方法一 winr 输入%tem%按回车键&#xff0c;出现的这些都是缓存文件可以按删除键删掉 方法二 winr 输入cleanmgr按回车键&#xff0c;选择清理的盘符&#xff0c;这里选择C盘&#xff0c;点击确定删除 方法三 在系统设置里手动删除 找到电脑里面的设置选项&#xff0c;找…

径向基函数插值

一、径向基函数的定义 如果 ∣ ∣ x 1 ∣ ∣ ∣ ∣ x 2 ∣ ∣ ||x_1||||x_2|| ∣∣x1​∣∣∣∣x2​∣∣&#xff0c;那么 ϕ ( x 1 ) ϕ ( x 2 ) \phi(x_1)\phi(x_2) ϕ(x1​)ϕ(x2​) 的函数 ϕ \phi ϕ 就是径向函数&#xff0c;即仅由 r ∣ ∣ x ∣ ∣ r||x|| r∣∣…

汽车雷达:实时SAR成像的实现

摘要: 众所周知,点云成像是目前实现汽车雷达感知最流行的方案,尤其是采用多级联实现的4D点云成像雷达,这是目前最有希望实现产品落地的技术方案之一。 今天重点分享关于汽车雷达SAR成像相关技术内容,这也证实了4D点云成像雷达并不一定就是汽车雷达成像唯一的方案,在业内…

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm)

Pytorch常用的函数(六)常见的归一化总结(BatchNorm/LayerNorm/InsNorm/GroupNorm) 常见的归一化操作有&#xff1a;批量归一化&#xff08;Batch Normalization&#xff09;、层归一化&#xff08;Layer Normalization&#xff09;、实例归一化&#xff08;Instance Normaliza…

【Linux驱动】Pinctrl子系统 | GPIO子系统 | 基于子系统的LED驱动程序

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f6f7;Pinctrl子系统&#x1f945;设备树中的Pinctrl子系统 &#x1f6f7;GPIO子系统…