a simple url shortener in Go (check it out at qurl.org)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
1.2 KiB

6 years ago
6 years ago
6 years ago
  1. package qurl
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "net/url"
  7. )
  8. type QURL struct {
  9. ID uint64
  10. URL string
  11. Created time.Time
  12. IP []byte
  13. Browser string
  14. }
  15. func (q *QURL) CheckValid() error {
  16. if q == nil {
  17. return fmt.Errorf("QURL is nil")
  18. }
  19. if q.URL == "" {
  20. return fmt.Errorf("URL may not be empty")
  21. }
  22. u, err := url.Parse(q.URL)
  23. if err != nil {
  24. return err
  25. }
  26. if !u.IsAbs() {
  27. return fmt.Errorf("Relative URLs are not allowed")
  28. }
  29. return nil
  30. }
  31. const alpha = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  32. const alphalen = uint64(len(alpha))
  33. func ToString(v uint64) string {
  34. var r strings.Builder
  35. var i uint64
  36. for i = v; i >= alphalen; i = (i / alphalen) - 1 {
  37. r.WriteByte(alpha[i%alphalen])
  38. }
  39. r.WriteByte(alpha[i])
  40. return r.String()
  41. }
  42. func FromString(s string) (uint64, error) {
  43. var r uint64
  44. vlen := uint64(len(s))
  45. for i := uint64(0); i < vlen; i++ {
  46. x := strings.IndexByte(alpha, s[i])
  47. if x == -1 {
  48. return 0, fmt.Errorf("Invalid character [%s]", s[i])
  49. }
  50. if i == 0 {
  51. r += uint64(x)
  52. } else {
  53. r += (uint64(x+1) * pow(alphalen, i))
  54. }
  55. }
  56. return r, nil
  57. }
  58. func pow(a, b uint64) uint64 {
  59. p := uint64(1)
  60. for b > 0 {
  61. if b&1 != 0 {
  62. p *= a
  63. }
  64. b >>= 1
  65. a *= a
  66. }
  67. return p
  68. }