搜索
bottom↓
回复: 82

推荐 Linux 源码中的 speck 加密,极简,可用于 stm8 和 51

  [复制链接]

出615入1076汤圆

发表于 2019-7-14 19:46:30 | 显示全部楼层 |阅读模式
本帖最后由 dukelec 于 2019-7-15 03:48 编辑

对我而言,Linux 内核代码是嵌入式的圣经,里面有很多值得我学习的东西,同时也为我带来很多宝藏。

做嵌入式和搞软件,非常重要的一点是选择,主系统选择 windows 还是 linux、选择 vbs 还是 python、选择 mfc 还是 html5、AD 还是 KiCad ...

众多的选择又决定了派系。如果选择的不好,你会发现,学了很多东西都白学,接下来遇到想学的新事务也会越发的力不从心。
选择的好,学的东西则会终身受用,精力比较集中,不用重复学习,不用很被动的跟在别人后面追。
所以,选择很重要,要抛开当下的舒适圈,不要随波逐流,要独立思考,选择长远对自己更有益的东西。

好了,不废话了,回到主题,很多人会觉得 linux 内核很神圣、很难懂,其实不然,譬如今天介绍的 speck 对称加解密算法,新的内核代码已经被删掉,因为它是美国国家安全局 NSA 设计的算法,开源社区的人担心有后门。
不过,我们用来做 bootloader 等加密是不需担心它是否真的有后门。很多场合可以代替 aes 加密。

原始的内核代码参见:
https://elixir.bootlin.com/linux/v4.18/source/crypto/speck.c
https://elixir.bootlin.com/linux ... lude/crypto/speck.h

包含注释等 N 多代码无关信息,c 文件一共才 307 行,包含了两个位宽版本,而且没啥依赖。

下面这个是我把代码搬到用户空间,写了一个小 main 文件测试的工程:

  1. #include <stdio.h>
  2. #include "speck.h"

  3. static speck64_t speck_ctx;
  4. static uint8_t key96[12] = {0,1,2,3,4,5,6,7,8,9,1,2}; // 密钥

  5. static uint8_t ori[8] = {1,2,3,4,5,6,7,8}; // 原始明文,一个 block 8 字节,正好 64 位
  6. static uint8_t enc[8] = {0}; // 存放加密得到的密文
  7. static uint8_t back[8]= {0}; // 存放再次解密得到的明文

  8. int main(void)
  9. {
  10.     crypto_speck64_setkey(&speck_ctx, key96, SPECK64_96_KEY_SIZE); // 第 3 个参数 8 位机版本已删掉,进一步减少开销
  11.     crypto_speck64_encrypt(&speck_ctx, enc, ori);
  12.     crypto_speck64_decrypt(&speck_ctx, back, enc);

  13.     printf("enc: %d %d %d %d %d %d %d %d\n", enc[0], enc[1], enc[2], enc[3], enc[4], enc[5], enc[6], enc[7]);
  14.     printf("back: %d %d %d %d %d %d %d %d\n", back[0], back[1], back[2], back[3], back[4], back[5], back[6], back[7]);

  15.     return 0;
  16. }
复制代码


这是最终搬到 8 位机的代码,只保留 64 位版本,不算注释,c 文件只有 70 多行,只是 put_unaligned_le32 和 get_unaligned_le32 这种通用函数里面,为移位加上显式类型转换,防止高位数据丢失而已。


为方便阅读,贴出相关代码:

头文件:
  1. #ifndef _CRYPTO_SPECK_H
  2. #define _CRYPTO_SPECK_H

  3. #define SPECK64_BLOCK_SIZE      8

  4. #define SPECK64_96_KEY_SIZE     12
  5. #define SPECK64_96_NROUNDS      26

  6. typedef struct {
  7.     uint32_t round_keys[SPECK64_96_NROUNDS];
  8. } speck64_t;

  9. void crypto_speck64_cal(const speck64_t *ctx, bool is_encrypt,
  10.                         uint8_t *out, const uint8_t *in);

  11. void crypto_speck64_setkey(speck64_t *ctx, const uint8_t *key);

  12. #endif /* _CRYPTO_SPECK_H */
复制代码


c 文件算法部分:

  1. static inline void speck64_round(uint32_t *x, uint32_t *y, uint32_t k)
  2. {
  3.     *x = ror32(*x, 8);
  4.     *x += *y;
  5.     *x ^= k;
  6.     *y = rol32(*y, 3);
  7.     *y ^= *x;
  8. }

  9. static inline void speck64_unround(uint32_t *x, uint32_t *y, uint32_t k)
  10. {
  11.     *y ^= *x;
  12.     *y = ror32(*y, 3);
  13.     *x ^= k;
  14.     *x -= *y;
  15.     *x = rol32(*x, 8);
  16. }

  17. void crypto_speck64_cal(const speck64_t *ctx, bool is_encrypt,
  18.                 uint8_t *out, const uint8_t *in)
  19. {
  20.     uint32_t y = get_unaligned_le32(in);
  21.     uint32_t x = get_unaligned_le32(in + 4);
  22.     int8_t i;

  23.     if (is_encrypt) {
  24.         for (i = 0; i < SPECK64_96_NROUNDS; i++)
  25.             speck64_round(&x, &y, ctx->round_keys[i]);
  26.     } else {
  27.         for (i = SPECK64_96_NROUNDS - 1; i >= 0; i--)
  28.             speck64_unround(&x, &y, ctx->round_keys[i]);
  29.     }

  30.     put_unaligned_le32(y, out);
  31.     put_unaligned_le32(x, out + 4);
  32. }

  33. void crypto_speck64_setkey(speck64_t *ctx, const uint8_t *key)
  34. {
  35.     uint32_t l[2];
  36.     uint32_t k;
  37.     int8_t i;

  38.     k = get_unaligned_le32(key);
  39.     l[0] = get_unaligned_le32(key + 4);
  40.     l[1] = get_unaligned_le32(key + 8);
  41.     for (i = 0; i < SPECK64_96_NROUNDS; i++) {
  42.         ctx->round_keys[i] = k;
  43.         speck64_round(&l[i % 2], &k, i);
  44.     }
  45. }
复制代码


辅助代码:(如果是小端 mcu,不需要 get_unaligned_le32 和 put_unaligned_le32, 直接用类型强制转化即可。)
  1. /**
  2. * rol32 - rotate a 32-bit value left
  3. * @word: value to rotate
  4. * @shift: bits to roll
  5. */
  6. static inline uint32_t rol32(uint32_t word, uint8_t shift)
  7. {
  8.     return (word << shift) | (word >> ((-shift) & 31));
  9. }

  10. /**
  11. * ror32 - rotate a 32-bit value right
  12. * @word: value to rotate
  13. * @shift: bits to roll
  14. */
  15. static inline uint32_t ror32(uint32_t word, uint8_t shift)
  16. {
  17.     return (word >> shift) | (word << (32 - shift));
  18. }

  19. static inline uint32_t get_unaligned_le32(const uint8_t *p)
  20. {
  21.     return p[0] | (uint16_t)p[1] << 8 | (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24;
  22. }

  23. /*
  24. static inline void put_unaligned_le16(uint16_t val, uint8_t *p)
  25. {
  26.     *p++ = val;
  27.     *p++ = val >> 8;
  28. } */

  29. static inline void put_unaligned_le32(uint32_t val, uint8_t *p)
  30. {
  31.     //put_unaligned_le16(val >> 16, p + 2);
  32.     //put_unaligned_le16(val, p);
  33.     p[0] = val & 0xff;
  34.     p[1] = (val >> 8) & 0xff;
  35.     p[2] = (val >> 16) & 0xff;
  36.     p[3] = val >> 24;
  37. }
复制代码


总的来说,几乎没啥改动,内核代码就可以直接搬到 8 位 mcu 运行。

内核里面还有很多类似的好东西,除了内核以外,linux 系统上的软件就更多更丰富了。平时用 linux 多,要什么软件很快能找到,而且有源码。不存在 windows 上很普通的小工具还要破解、被中毒、弹广告。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2019-7-14 20:20:07 | 显示全部楼层
666,记得以前有个PTHREAD线程好像也是来自linux,也能移植方便到普通MCU

出0入0汤圆

发表于 2019-7-14 21:27:31 | 显示全部楼层
Linux      speck     加密   极简,

出0入0汤圆

发表于 2019-7-14 21:38:58 | 显示全部楼层
收藏,替换我的bootloader试试

出0入362汤圆

发表于 2019-7-14 21:40:20 | 显示全部楼层
duxingkei 发表于 2019-7-14 20:20
666,记得以前有个PTHREAD线程好像也是来自linux,也能移植方便到普通MCU

pthread能移植到普通MCU?具体说说?

出0入0汤圆

发表于 2019-7-14 21:48:18 | 显示全部楼层
本帖最后由 pazulin 于 2019-7-14 21:51 编辑

非常好的参考!谢谢!! 不单单用在bootloader ,很多场合可用

出0入0汤圆

发表于 2019-7-14 21:55:35 | 显示全部楼层
保存下。Linux      speck     加密   极简

出0入0汤圆

发表于 2019-7-14 22:04:10 | 显示全部楼层
感谢分享,

出0入0汤圆

发表于 2019-7-14 22:10:34 | 显示全部楼层
谢谢 分享,先支持后看货。

出0入0汤圆

发表于 2019-7-14 23:01:45 来自手机 | 显示全部楼层
mark,备用

出0入0汤圆

发表于 2019-7-14 23:17:08 | 显示全部楼层
speck 加密,学习了

出0入618汤圆

发表于 2019-7-14 23:49:09 | 显示全部楼层
XXTEA更简单。

出0入0汤圆

发表于 2019-7-14 23:52:18 | 显示全部楼层
speck 加密

出140入115汤圆

发表于 2019-7-14 23:59:42 来自手机 | 显示全部楼层
多谢分享

出0入0汤圆

发表于 2019-7-15 00:00:17 | 显示全部楼层
收藏了,好东西

出615入1076汤圆

 楼主| 发表于 2019-7-15 00:09:19 | 显示全部楼层
本帖最后由 dukelec 于 2019-7-15 12:37 编辑


我曾经有对比过,xxtea wikipedia 上面那个代码虽然看起来不长,但那个 MX macro 展开还是挺占代码空间的 。
1 楼代码中的函数去掉 inline, 会更加节省代码空间,8 位机编程,经常代码空间不足,省一两个字节都是好的。
虽然 speck 的 key 展开之后比较占内存,但做为 bootloader, 内存不用白不用。

speck 比 tea 更小更快,支持更多不同的 key 大小,见楼下 #18 楼比较。

我当时主要是看了 #18 楼的比较才选了 speck, 不过你这么一提醒,我又对比了下:
xxtea 支持指定数据长度,核心操作步骤更多,更占代码空间;
xtea 是固定 8 字节数据长度,xtea 比较简单,可以把核心位操作打包成非 inline 函数,以减少代码空间。

Linux 内核只支持 xtea, 没有 xxtea, 所以,我觉得可以试试 xtea, 之前不想试是因为:总觉得有高版本的就不愿意用低版本,另外误以为 tea 的 key size 更长 footprint 会更大。
我抽空对比下,都用最节省 flash 的写法,对比 xtea 和 speck 的 flash 占用情况,感觉自己有点被 #18 楼的文章误导。

顺便贴出内核的 xtea 代码:
  1. #define XTEA_KEY_SIZE                16
  2. #define XTEA_BLOCK_SIZE                8
  3. #define XTEA_ROUNDS                32
  4. #define XTEA_DELTA                0x9e3779b9

  5. struct xtea_ctx {
  6.         u32 KEY[4];
  7. };

  8. static void xtea_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  9. {
  10.         u32 y, z, sum = 0;
  11.         u32 limit = XTEA_DELTA * XTEA_ROUNDS;
  12.         struct xtea_ctx *ctx = crypto_tfm_ctx(tfm);
  13.         const __le32 *in = (const __le32 *)src;
  14.         __le32 *out = (__le32 *)dst;

  15.         y = le32_to_cpu(in[0]);
  16.         z = le32_to_cpu(in[1]);

  17.         while (sum != limit) {
  18.                 y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]);
  19.                 sum += XTEA_DELTA;
  20.                 z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]);
  21.         }
  22.        
  23.         out[0] = cpu_to_le32(y);
  24.         out[1] = cpu_to_le32(z);
  25. }

  26. static void xtea_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  27. {
  28.         u32 y, z, sum;
  29.         struct tea_ctx *ctx = crypto_tfm_ctx(tfm);
  30.         const __le32 *in = (const __le32 *)src;
  31.         __le32 *out = (__le32 *)dst;

  32.         y = le32_to_cpu(in[0]);
  33.         z = le32_to_cpu(in[1]);

  34.         sum = XTEA_DELTA * XTEA_ROUNDS;

  35.         while (sum) {
  36.                 z -= ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 & 3]);
  37.                 sum -= XTEA_DELTA;
  38.                 y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
  39.         }
  40.        
  41.         out[0] = cpu_to_le32(y);
  42.         out[1] = cpu_to_le32(z);
  43. }
复制代码

出0入0汤圆

发表于 2019-7-15 00:15:55 来自手机 | 显示全部楼层
有没有人对比下,和aes加密,哪个占用存储资源小

出615入1076汤圆

 楼主| 发表于 2019-7-15 00:40:04 | 显示全部楼层
本帖最后由 dukelec 于 2019-7-15 05:17 编辑
wx-ta 发表于 2019-7-15 00:15
有没有人对比下,和aes加密,哪个占用存储资源小


你这是拿 单车 与 跑车 做比较。。。

这有个比较的报告,文末有总结文字,还有个表:
https://pdfs.semanticscholar.org ... 6a78fea67b3b5dd.pdf




如果 mcu 自带硬件 aes,那么可以考虑用硬件 aes.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2019-7-15 08:26:13 | 显示全部楼层
SPECK加密,留个爪,新许哪天会用到。之前在数据传输上倒是用过TEA,不过是在PC上

出10入12汤圆

发表于 2019-7-15 08:28:15 | 显示全部楼层

Linux      speck     加密   极简,

出0入0汤圆

发表于 2019-7-15 08:31:23 | 显示全部楼层
一直在用XTEA,不懂密码学,但是感觉算法和XTEA很相似,都是和秘钥做N轮迭代运算得到密文。

出0入0汤圆

发表于 2019-7-15 08:42:20 | 显示全部楼层
收藏一下。多谢!

出0入0汤圆

发表于 2019-7-15 08:44:49 | 显示全部楼层
收藏一下,好东西。

出0入0汤圆

发表于 2019-7-15 08:49:34 | 显示全部楼层


Linux      speck     加密   极简

出40入42汤圆

发表于 2019-7-15 08:50:53 | 显示全部楼层
感谢分享

出0入4汤圆

发表于 2019-7-15 08:53:17 | 显示全部楼层
感谢分享,留脚印

出0入0汤圆

发表于 2019-7-15 08:59:26 | 显示全部楼层
我用TEA加密,单片机端和电脑端的C#算出来加密后的值不一样。有什么算法加 密效果不差,加密后的值一样的吗?这样可以在对方还原。

出0入0汤圆

发表于 2019-7-15 09:59:37 来自手机 | 显示全部楼层
本帖最后由 fnems 于 2019-7-15 10:00 编辑
liansh2002 发表于 2019-7-15 08:31
一直在用XTEA,不懂密码学,但是感觉算法和XTEA很相似,都是和秘钥做N轮迭代运算得到密文。 ...


很多对称加密都是基于多轮feistel网络迭代来实现位扩散,tea和这个都是。
你觉得眼熟的就是这个feistel网络,可以找维基百科看看。有点对称加密基石的意思。

AES有点不一样,是基于s-box和p-box变换。

出0入0汤圆

发表于 2019-7-15 10:05:46 来自手机 | 显示全部楼层
speck     加密   极简  谢谢

出0入0汤圆

发表于 2019-7-15 10:06:14 | 显示全部楼层
学习一下 对称加密

出0入0汤圆

发表于 2019-7-15 10:16:14 | 显示全部楼层
MARK 加密算法

出5入10汤圆

发表于 2019-7-15 10:18:22 | 显示全部楼层
mark,收藏下,有机会用上去试试

出0入0汤圆

发表于 2019-7-15 10:25:05 | 显示全部楼层
这比AES有多大的优势呢?

出0入13汤圆

发表于 2019-7-15 10:49:56 | 显示全部楼层
speck 加密 ,不错
用来做通信加密应该不错,以后应该用得上

出0入0汤圆

发表于 2019-7-15 11:00:49 来自手机 | 显示全部楼层
看了一下,这个speck用在BL上很合适,源码也较精简

出0入0汤圆

发表于 2019-7-15 11:04:09 | 显示全部楼层
确实,Linux内核里面有很多好东西,我03年的时候看了list的实现,真是佩服。

出0入0汤圆

发表于 2019-7-15 11:12:09 | 显示全部楼层
Linux      speck     加密

出90入4汤圆

发表于 2019-7-15 11:16:08 来自手机 | 显示全部楼层
实际怎么使用?

出0入0汤圆

发表于 2019-7-15 11:53:35 来自手机 | 显示全部楼层
好东西,收藏了

出615入1076汤圆

 楼主| 发表于 2019-7-15 12:31:09 | 显示全部楼层
本帖最后由 dukelec 于 2019-7-15 12:34 编辑
cycisok 发表于 2019-7-15 08:59
我用TEA加密,单片机端和电脑端的C#算出来加密后的值不一样。有什么算法加 密效果不差,加密后的值一样的吗 ...


相同配置,不同软件算出来值必须相同,你结果不同肯定是你代码有 bug.
请检查 左 移位是否丢数据,iar stm8 char 左移后存入 int,高出 8 位数据会丢失。
更重要的是,要检查大小端不同带来的差异,pc、stm32 是小端,stm8 iar、51 keil 是大端。

参考 linux 代码的好处之一是:大小端都兼容,不会因为大小端不同而出错。

出615入1076汤圆

 楼主| 发表于 2019-7-15 12:33:18 | 显示全部楼层
小溪 发表于 2019-7-15 10:25
这比AES有多大的优势呢?

aes stm8s103 级别的 8 位机装不下。

出0入0汤圆

发表于 2019-7-15 13:24:50 | 显示全部楼层
好动动,下载留用。

出0入0汤圆

发表于 2019-7-15 13:32:29 | 显示全部楼层
好东西,mark    speck 加密

出0入0汤圆

发表于 2019-7-15 13:41:23 | 显示全部楼层
好东西,先mark一下,speck 加密   

出0入0汤圆

发表于 2019-7-15 13:59:19 | 显示全部楼层
mark                           

出0入0汤圆

发表于 2019-7-15 14:31:36 | 显示全部楼层
咱是不是也跟风mark一把。

出0入0汤圆

发表于 2019-7-15 15:11:31 | 显示全部楼层
这分享是好东西呀,研究中

出0入0汤圆

发表于 2019-7-15 21:38:32 | 显示全部楼层
dukelec 发表于 2019-7-15 12:33
aes stm8s103 级别的 8 位机装不下。

终于等到了这个回复,以前一直用AES的。回头试下Speck~

出0入0汤圆

发表于 2019-7-15 23:11:07 | 显示全部楼层
谢谢楼主推荐呢
有个问题呢,在Flash中存储的是明文吗?
对于加密,是对编译软件生成文件进行加密,需要一个上位机进行加密,然后在MCU端解密,再把明文写道flash中吗?

出0入0汤圆

发表于 2019-7-15 23:37:30 | 显示全部楼层
crazydtone 发表于 2019-7-15 23:11
谢谢楼主推荐呢
有个问题呢,在Flash中存储的是明文吗?
对于加密,是对编译软件生成文件进行 ...

对的,是这样。

出0入0汤圆

发表于 2019-7-16 08:22:22 | 显示全部楼层
楼主高手。收藏下备用!

出0入0汤圆

发表于 2019-7-16 08:34:53 | 显示全部楼层
speck 加密

出0入0汤圆

发表于 2019-7-16 08:39:27 | 显示全部楼层
speck通讯加密收藏下

出10入0汤圆

发表于 2019-7-16 14:12:50 来自手机 | 显示全部楼层
Mark,收藏下!

出50入0汤圆

发表于 2019-7-16 15:15:42 | 显示全部楼层
speck     加密   极简

出0入0汤圆

发表于 2019-7-18 21:53:23 来自手机 | 显示全部楼层
spek 加密

出0入0汤圆

发表于 2019-7-19 12:54:27 | 显示全部楼层
mark

linux 加密算法

XXTEA更简单

出0入0汤圆

发表于 2019-7-19 13:14:12 | 显示全部楼层
mark, 回头用得上再来研究

出0入0汤圆

发表于 2019-7-19 17:04:36 | 显示全部楼层
收藏  加密算法

出0入0汤圆

发表于 2019-7-19 22:16:08 | 显示全部楼层
Linux      speck     加密   极简,

出0入0汤圆

发表于 2019-7-20 01:33:22 来自手机 | 显示全部楼层
收藏了.好

出0入0汤圆

发表于 2019-7-20 01:43:56 | 显示全部楼层
学习了 谢谢 后续可以用

出0入17汤圆

发表于 2019-7-20 08:59:56 | 显示全部楼层
已收藏,多谢楼主!

出10入0汤圆

发表于 2019-8-7 11:05:09 | 显示全部楼层
谢谢分享!
下载试试。

出0入0汤圆

发表于 2019-8-7 11:39:37 | 显示全部楼层
Linux      speck     加密

出0入8汤圆

发表于 2019-8-7 11:45:47 | 显示全部楼层
看起来很高科技。
惭愧啊,工作十余年,从来没碰过 Linux,更不用说看源码了。

出0入0汤圆

发表于 2019-8-7 11:53:14 | 显示全部楼层

Linux      speck     加密   极简

出0入0汤圆

发表于 2019-8-7 12:07:59 | 显示全部楼层
linux speck加密 ,mark,多谢分享

出0入420汤圆

发表于 2021-1-2 22:58:06 | 显示全部楼层
inux speck加密 ,mark

出100入101汤圆

发表于 2021-1-2 23:57:15 来自手机 | 显示全部楼层
lz,大神

出10入120汤圆

发表于 2021-1-3 07:49:26 来自手机 | 显示全部楼层
Linux      speck     加密

出200入0汤圆

发表于 2021-1-3 08:14:26 来自手机 | 显示全部楼层
666敏感的意识  标记一下。多谢分享 Linux      speck     加密   极简

出0入0汤圆

发表于 2021-1-3 12:03:05 | 显示全部楼层
speck 加密,适用于 bootloader,谢谢。

出0入4汤圆

发表于 2021-1-3 12:07:50 | 显示全部楼层
speck 加密,极简,可用于 stm8 和 51

出0入0汤圆

发表于 2021-1-5 13:41:11 | 显示全部楼层
第一次接触加密算法。

出0入0汤圆

发表于 2021-1-5 14:00:54 | 显示全部楼层
Linux      speck     加密

出50入0汤圆

发表于 2021-1-5 15:25:17 | 显示全部楼层

Linux      speck     加密   极简

出20入0汤圆

发表于 2021-1-6 00:04:39 | 显示全部楼层
speck 对称加解密算法

出0入0汤圆

发表于 2021-1-6 09:34:39 | 显示全部楼层
保存下。Linux      speck     加密   极简  思路比较开阔,  tea xtea aes, 我只用过AES

出0入0汤圆

发表于 2021-1-6 09:56:02 | 显示全部楼层
好东西,谢谢楼主

出0入0汤圆

发表于 2021-1-6 10:42:24 | 显示全部楼层
Linux      speck 留个备用 谢谢

出0入0汤圆

发表于 2021-1-6 11:08:11 来自手机 | 显示全部楼层
xchacha 听说专为arm优化过的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 03:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表