Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cl-nixbase32 initial iteration #1

Closed
kisp opened this issue May 24, 2024 · 6 comments
Closed

cl-nixbase32 initial iteration #1

kisp opened this issue May 24, 2024 · 6 comments
Assignees

Comments

@kisp
Copy link
Owner

kisp commented May 24, 2024

No description provided.

@kisp kisp self-assigned this May 24, 2024
@kisp
Copy link
Owner Author

kisp commented May 24, 2024

go-nix/nixbase32/nixbase32.go at dev · zombiezen/go-nix
https://github.com/zombiezen/go-nix/blob/dev/nixbase32/nixbase32.go

@kisp
Copy link
Owner Author

kisp commented May 24, 2024

;; Define the alphabet used in Nix base32 encoding
(defparameter *alphabet* "0123456789abcdfghijklmnpqrsvwxyz")

;; Function to decode a nixbase32 string into bytes
(defun decode-string (s)
  (let ((dst (make-array (decoded-len (length s)))))
    (multiple-value-bind (n err)
        (decode dst (coerce s 'list))
      (subseq dst 0 n))))

;; Function to decode nixbase32 encoded data
(defun decode (dst src)
  (let ((max-dst-size (decoded-len (length src))))
    (loop for n from 0 below (length src)
          for b = (* n 5)
          for i = (floor b 8)
          for j = (mod b 8)
          for c = (elt (reverse src) n)
          for digit = (position c *alphabet*)
          do (if (null digit)
                 (return-from decode (values i (error "Decode base32: character not in Nix alphabet")))
                 (setf (aref dst i) (logior (aref dst i) (ash digit j)))
                 (let ((carry (ash digit (- 8 j))))
                   (if (< (1+ i) max-dst-size)
                       (setf (aref dst (1+ i)) (logior (aref dst (1+ i)) carry))
                       (if (plusp carry)
                           (return-from decode (values i (error "Decode base32: non-zero padding"))))))))))

;; Function to validate a nixbase32 encoded string
(defun validate-string (src)
  (let ((max-dst-size (decoded-len (length src))))
    (loop for n from 0 below (length src)
          for b = (* n 5)
          for i = (floor b 8)
          for j = (mod b 8)
          for c = (elt (reverse src) n)
          for digit = (position c *alphabet*)
          do (if (null digit)
                 (return-from validate-string (error "Decode base32: character not in Nix alphabet"))
                 (when (>= (1+ i) max-dst-size)
                   (let ((carry (ash digit (- 8 j))))
                     (when (plusp carry)
                       (return-from validate-string (error "Decode base32: non-zero padding")))))))))

;; Function to get the length in bytes of the base32 encoding
(defun encoded-len (n)
  (ceiling (* (+ (* n 8) 4) 5)))

;; Function to get the length in bytes of the decoded data
(defun decoded-len (n)
  (floor (* n 5) 8))

;; Function to encode data using nixbase32
(defun encode (dst src)
  (let ((n (encoded-len (length src))))
    (dotimes (n (- n 1) dst)
      (let* ((b (* n 5))
             (i (floor b 8))
             (j (mod b 8))
             (c (ash (aref src i) (- j))))
        (when (< (1+ i) (length src))
          (setf c (logior c (ash (aref src (1+ i)) (- 8 j)))))
        (push (aref *alphabet* (logand c #x1f)) dst)))))

;; Function to encode data to nixbase32 string
(defun encode-to-string (src)
  (let ((n (encoded-len (length src)))
        (result ""))
    (dotimes (n (- n 1) result)
      (let* ((b (* n 5))
             (i (floor b 8))
             (j (mod b 8))
             (c (ash (aref src i) (- j))))
        (when (< (1+ i) (length src))
          (setf c (logior c (ash (aref src (1+ i)) (- 8 j)))))
        (setf result (concatenate 'string (string (aref *alphabet* (logand c #x1f))) result))))))

;; Predicate to check if a byte is part of the nixbase32 alphabet
(defun is-nixbase32-char-p (c)
  (or (and (char<= #\0 c #\9))
      (and (char<= #\a c #\z)
           (not (member c '(#\e #\o #\u #\t))))))

@kisp
Copy link
Owner Author

kisp commented May 24, 2024

nix-prefetch-url - Nix Reference Manual
https://nixos.org/manual/nix/stable/command-ref/nix-prefetch-url

@kisp
Copy link
Owner Author

kisp commented May 24, 2024

13:48 $ nix-prefetch-url http://pauldist.kisp.in/archive/hgetopt-0.0.4.tgz
path is '/nix/store/74l2bfic29rbl14wnhdwdrxm84v8qqxs-hgetopt-0.0.4.tgz'
1ak0qjw1r1idnv0847fvyj3jsd3m7z8674c41p76hr36d98n9wk2

13:48 $ nix-hash --flat --type sha256 /nix/store/74l2bfic29rbl14wnhdwdrxm84v8qqxs-hgetopt-0.0.4.tgz
62f264516a666468ce0d849163d03f75342d87f4db1d82c0b62d861cb8c460aa

13:48 $ nix-hash --flat --type sha256 --base32 /nix/store/74l2bfic29rbl14wnhdwdrxm84v8qqxs-hgetopt-0.0.4.tgz
1ak0qjw1r1idnv0847fvyj3jsd3m7z8674c41p76hr36d98n9wk2

@kisp
Copy link
Owner Author

kisp commented May 24, 2024

RFC 4648 - The Base16, Base32, and Base64 Data Encodings
https://datatracker.ietf.org/doc/html/rfc4648#section-6

@kisp
Copy link
Owner Author

kisp commented May 24, 2024

Document that base32 hashes are not the base32 everyone expects · Issue #4354 · NixOS/nix
NixOS/nix#4354

kisp added a commit that referenced this issue May 24, 2024
kisp added a commit that referenced this issue May 30, 2024
kisp added a commit that referenced this issue May 30, 2024
@kisp kisp closed this as completed May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant