OSDN Git Service

libext2fs: add ext2fs_digest_encode()
authorTheodore Ts'o <tytso@mit.edu>
Sun, 8 Mar 2015 22:15:47 +0000 (18:15 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 8 Mar 2015 22:15:47 +0000 (18:15 -0400)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/Makefile.in
lib/ext2fs/digest_encode.c [new file with mode: 0644]
lib/ext2fs/ext2fs.h

index 30a393c..63aab46 100644 (file)
@@ -73,6 +73,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
        csum.o \
        dblist.o \
        dblist_dir.o \
+       digest_encode.o \
        dirblock.o \
        dirhash.o \
        dir_iterate.o \
@@ -149,6 +150,7 @@ SRCS= ext2_err.c \
        $(srcdir)/csum.c \
        $(srcdir)/dblist.c \
        $(srcdir)/dblist_dir.c \
+       $(srcdir)/digest_encode.c \
        $(srcdir)/dirblock.c \
        $(srcdir)/dirhash.c \
        $(srcdir)/dir_iterate.c \
@@ -271,6 +273,11 @@ tst_badblocks: tst_badblocks.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
        $(Q) $(CC) -o tst_badblocks tst_badblocks.o $(ALL_LDFLAGS) \
                $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
+tst_digest_encode: $(srcdir)/digest_encode.c $(srcdir)/ext2_fs.h
+       $(E) "  CC $@"
+       $(Q) $(CC) $(ALL_LDFLAGS) $(ALL_CFLAGS) -o tst_digest_encode \
+               $(srcdir)/sha256.c -DUNITTEST $(SYSLIBS)
+
 tst_icount: $(srcdir)/icount.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
        $(E) "  LD $@"
        $(Q) $(CC) -o tst_icount $(srcdir)/icount.c -DDEBUG \
@@ -572,6 +579,7 @@ clean::
                tst_bitops tst_types tst_icount tst_super_size tst_csum \
                tst_bitmaps tst_bitmaps_out tst_extents tst_inline \
                tst_inline_data tst_inode_size tst_bitmaps_cmd.c \
+               tst_digest_encode \
                ext2_tdbtool mkjournal debug_cmds.c tst_cmds.c extent_cmds.c \
                ../libext2fs.a ../libext2fs_p.a ../libext2fs_chk.a \
                crc32c_table.h gen_crc32ctable tst_crc32c tst_libext2fs \
@@ -733,6 +741,12 @@ dblist_dir.o: $(srcdir)/dblist_dir.c $(top_builddir)/lib/config.h \
  $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
  $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
  $(srcdir)/bitops.h
+digest_encode.o: $(srcdir)/digest_encode.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2_fs.h \
+ $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
 dirblock.o: $(srcdir)/dirblock.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
diff --git a/lib/ext2fs/digest_encode.c b/lib/ext2fs/digest_encode.c
new file mode 100644 (file)
index 0000000..85e7128
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * lib/ext2fs/digest_encode.c
+ *
+ * A function to encode a digest using 64 characters that are valid in a
+ * filename per ext2fs rules.
+ *
+ * Written by Uday Savagaonkar, 2014.
+ *
+ * Copyright 2014 Google Inc.  All Rights Reserved.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include "ext2fs.h"
+
+/**
+ * ext2fs_digest_encode() -
+ *
+ * Encodes the input digest using characters from the set [a-zA-Z0-9_+].
+ * The encoded string is roughly 4/3 times the size of the input string.
+ */
+int ext2fs_digest_encode(const char *src, unsigned long len, char *dst)
+{
+       static const char *lookup_table =
+               "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+";
+       unsigned num_chunks, i;
+       char tmp_buf[3];
+       unsigned c0, c1, c2, c3;
+
+       num_chunks = len/3;
+       for (i = 0; i < num_chunks; i++) {
+               c0 = src[3*i] & 0x3f;
+               c1 = (((src[3*i]>>6)&0x3) | ((src[3*i+1] & 0xf)<<2)) & 0x3f;
+               c2 = (((src[3*i+1]>>4)&0xf) | ((src[3*i+2] & 0x3)<<4)) & 0x3f;
+               c3 = (src[3*i+2]>>2) & 0x3f;
+               dst[4*i] = lookup_table[c0];
+               dst[4*i+1] = lookup_table[c1];
+               dst[4*i+2] = lookup_table[c2];
+               dst[4*i+3] = lookup_table[c3];
+       }
+       if (i*3 < len) {
+               memset(tmp_buf, 0, 3);
+               memcpy(tmp_buf, &src[3*i], len-3*i);
+               c0 = tmp_buf[0] & 0x3f;
+               c1 = (((tmp_buf[0]>>6)&0x3) | ((tmp_buf[1] & 0xf)<<2)) & 0x3f;
+               c2 = (((tmp_buf[1]>>4)&0xf) | ((tmp_buf[2] & 0x3)<<4)) & 0x3f;
+               c3 = (tmp_buf[2]>>2) & 0x3f;
+               dst[4*i] = lookup_table[c0];
+               dst[4*i+1] = lookup_table[c1];
+               dst[4*i+2] = lookup_table[c2];
+               dst[4*i+3] = lookup_table[c3];
+       }
+       return 4*(i+1);
+}
+
+#ifdef UNITTEST
+static const struct {
+       unsigned char d[32];
+       const unsigned char *ed;
+} tests[] = {
+       { { 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+           0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+           0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+           0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 },
+       "JdlXcHj+CqHM7tpYz_wUKCIRbrozBojtKwzMBGNu4wfa"
+       },
+       { { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
+           0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
+           0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+           0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad },
+       "6INf+_yapREqbbK3D5QiJa7aHnQLxOhN0cX+Hjpav0ka"
+       },
+       { { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
+           0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
+           0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
+           0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 },
+       "K0OAHjTb4GB5aBYKm4dy5mkpKNfz+hYz2ZE7uNX2gema"
+       },
+};
+
+int main(int argc, char **argv)
+{
+       int i;
+       int errors = 0;
+       unsigned char tmp[44];
+
+       for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
+               ext2fs_digest_encode(tmp, tests[i].d, 32);
+               printf("Test Digest %d: ", i);
+               if (memcmp(tmp, tests[i].ed, 44) != 0) {
+                       printf("FAILED\n");
+                       errors++;
+               } else
+                       printf("OK\n");
+       }
+       return errors;
+}
+
+#endif /* UNITTEST */
index 82c09d8..e9d9198 100644 (file)
@@ -1085,6 +1085,10 @@ extern errcode_t
                                              void      *priv_data),
                                  void *priv_data);
 
+/* digest_encode.c */
+#define EXT2FS_DIGEST_SIZE EXT2FS_SHA256_LENGTH
+extern int ext2fs_digest_encode(const char *src, unsigned long len, char *dst);
+
 /* dirblock.c */
 extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
                                       void *buf);